written with stackedit.《集合論與圖論》這門課程有一道作業題,要求同學們求出\(\\)的所有滿足以 下條件的子集:若 \(x\) 在該子集中,則 \(2x\) 和 \(3x\) 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題:對於任意乙個正整數 \(n\leq 100000\),如何求出\(\\) 的滿足上述約束條件的子集的個數(只需輸出對 \(1000000001\) 取模的結果),現在這個問題就 交給你了。
只有一行,其中有乙個正整數 \(n\),\(30\%\)的資料滿足 \(n\leq20\)。
僅包含乙個正整數,表示\(\\)有多少個滿足上述約束條件 的子集。
【樣例解釋】
有\(8\) 個集合滿足要求,分別是\(\emptyset\),\(\\),\(\\),\(\\),\(\\),\(\\),\(\\),\(\\).
\[\begin
1 & 3 & 9 & 27 & ...\\
2 & 6 & 18 & 54 & ...\\
4 & 12 & 36 & 108 & ...\\
8 & 24 & 72 & 216 & ...\\
... & ... & ... & ... & ...\\
\end \quad\]
左上角的數增大時,矩陣沒有填入數字的部分也不斷增大.手動\(memset\).
#includeusing namespace std;
typedef long long lovelive;
inline int read()
while (jp>='0'&&jp<='9')
return out*fh;
}const int p=1e9+1;
inline int add(int a,int b)
inline int mul(int a,int b)
const int maxn=1e5+10;
int n;
int vis[maxn];
int martix[20][20];
int limit[20];//第i行的邊界
int ans=1;
int r,c;
int judge(int st)
return 1;
}vectorg;
void build_martix(int x)
martix[i][1]=p;
vis[p]=1;
for(int j=2;j<20;++j)
martix[i][j]=p;
vis[p]=1;
}} g.clear();
int s=1break;
if(check(i,st))
res=add(res,dfs(k-1,i));
} return res;
}void solve(int x)//以x為左上角構造矩陣的方案數
//memset(f,-1,sizeof f);
ans=mul(ans,dfs(r+1,0));
}int main()
bzoj 2734 集合選數
構造矩陣 1 3 9 27 2 6 18 54 4 12 36 108 每個數是上面的數乘2,左面的數乘3。這樣進行狀壓dp就是相鄰的格仔不能選的方案數。如何判斷乙個二進位制數沒有兩個連續的1?x x 1 0 如果有的數沒有出現過,就以它為左上角元素再構造乙個矩陣。這是怎麼想到的?include i...
BZOJ2734 集合選數
集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 3x 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題 對於任意乙個正整數 n 100000,如何求出 的滿足上述約束條件的子集的個數 只需輸出對 1,000,...
BZOJ 2734 集合選數(狀態壓縮DP)
題意 給出乙個由1到n的數字組成的集合。定義合法子集為若x在子集中則2x 3x均不能在子集中。求有多少個合法的子集。思路 1 3 9 2 6 18 4 12 36 對於上面的矩陣,我們發現就等價於不選相鄰數字的方案數。因此列舉每個還沒有用到的數字,建立以該數字為左上角的矩陣。接著就是狀態壓縮dp。i...