time limit: 10 sec memory limit: 128 mb
submit: 889 solved: 523
[submit][status][discuss]
description
《集合論與圖論》這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集:若 x 在該子集中,則 2x 和 3x 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題:對於任意乙個正整數 n≤100000,如何求出 的滿足上述約束條件的子集的個數(只需輸出對 1,000,000,001 取模的結果),現在這個問題就 交給你了。
input
只有一行,其中有乙個正整數 n,30%的資料滿足 n≤20。
output
僅包含乙個正整數,表示有多少個滿足上述約束條件 的子集。
sample input
4
sample output
8
【樣例解釋】
有8 個集合滿足要求,分別是空集,,,,,,,。
很巧妙的乙個構造方法構造乙個矩陣,使得f[
i][j
+1]=
f[i]
[j]∗
3,f[
i+1]
[j]=
f[i]
[j]∗
2 這樣構造出矩陣之後,矩陣中的乙個元素和他四個方向上的元素就不能同時選。
n的範圍是105
,如果把每一行都壓成乙個狀態的話,那麼最多只有lo
g3(10
5)≈11
列,lo
g2(10
5)≈17
行。轉移的時候就列舉所有狀態就行了。
有乙個問題需要注意,不是所有數都能放在乙個矩陣裡的,所以要構建很多次矩陣。
時間複雜度:o(
17∗211
∗211)
≈7∗10
7
#include
#include
#include
using
namespace
std;
#define ll long long
#define mod 1000000001
const
int n=20;
const
int m=100010;
bool flag[m];
int n,f[n][1
inline
int calc(int x)
for(m=i,j=1;j<=n;++j)
}for(i=1;i<=m;++i)
for(i=0;i<(1
>1))&&!(limit[1]&i)) f[1][i]=1;
for(i=2;i<=m;++i)
for(j=0;j<(1
>1))&&!(limit[i]&j))
for(f[i][j]=0,k=0;k<(1
>1))&&!(limit[i-1]&k)&&!(k&j))
f[i][j]=(f[i][j]+f[i-1][k])%mod;
int sum=0;
for(i=0;i<(1
>1))&&!(i&limit[m])) sum+=f[m][i];
return sum;
}int main()
bzoj2734 HNOI2012 集合選數
time limit 10 sec memory limit 128 mb submit 831 solved 487 submit status discuss 集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 3x 不能在該子集中。同...
bzoj2734 HNOI2012 集合選數
題目鏈結 集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 3x 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題 對於任意乙個正整數 n 100000,如何求出 的滿足上述約束條件的子集的個數 只需輸出對 1...
BZOJ2734 HNOI2012 集合選數
description 求出集合中,滿足 諾x在該集合中,2x與3x不在集合。的所有子集的個數。對答案mod 1000000001。題解這個題目很要思維了,反正我沒想出來,但看了題解十分佩服。我們構造乙個矩陣,x3x 9x.3j x 2x6x 18x.2i x 2i 3jx 可以發現,滿足要求的子集...