bzoj2734 HNOI2012 集合選數

2021-07-30 02:13:51 字數 1229 閱讀 7407

題目鏈結

《集合論與圖論》這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集:若 x 在該子集中,則 2x 和 3x 不能在該子集中。同學們不喜歡這種具有列舉性 質的題目,於是把它變成了以下問題:對於任意乙個正整數 n≤100000,如何求出 的滿足上述約束條件的子集的個數(只需輸出對 1,000,000,001 取模的結果),現在這個問題就 交給你了。

只有一行,其中有乙個正整數 n,30%的資料滿足 n≤20。

僅包含乙個正整數,表示有多少個滿足上述約束條件 的子集。

4【樣例解釋】

有8 個集合滿足要求,分別是空集,,,,,,,。

思路題。。我反正是想不出。

考慮列出乙個這樣的矩陣 ⎡⎣

⎢124

36129

183627…

54…108…⎤⎦

⎥ 這個矩陣不會很大,20行20列以內。

而我們取數的限制就是在這個矩陣中相鄰的兩個數不能同時取。

那麼顯然可以把一行壓成乙個二進位制數,然後狀壓dp解決。

注意到乙個矩陣不可能包含1…

n 的所有數,那麼我們就標記已經出現過的數,對於沒出現過的數將它作為矩陣的第一行第一列的元素再計算一遍,因為不同矩陣的答案互不干擾,所以用乘法原理相乘起來即可。

#include

using

namespace

std;

typedef

long

long ll;

const

int n = 100000 + 10, mod = 1000000001, m = 20;

int n, vis[n], a[m][m], r[m];

ll ans = 1, f[m][n];

ll cal(int x)

}vis[a[i][1]] = 1;

for(int j = 2; j < m; j++)

vis[a[i][j]] = 1;}}

for(int i = 0; i <= c; i++) for(int j = 0; j < (1

<0;

f[c+1][0] = 0;

f[0][0] = 1;

for(int i = 0; i <= c; i++)}}

return f[c+1][0];

}void work()

int main()

bzoj2734 HNOI2012 集合選數

time limit 10 sec memory limit 128 mb submit 831 solved 487 submit status discuss 集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 3x 不能在該子集中。同...

bzoj2734 HNOI2012 集合選數

time limit 10 sec memory limit 128 mb submit 889 solved 523 submit status discuss description 集合論與圖論 這門課程有一道作業題,要求同學們求出的所有滿足以 下條件的子集 若 x 在該子集中,則 2x 和 ...

BZOJ2734 HNOI2012 集合選數

description 求出集合中,滿足 諾x在該集合中,2x與3x不在集合。的所有子集的個數。對答案mod 1000000001。題解這個題目很要思維了,反正我沒想出來,但看了題解十分佩服。我們構造乙個矩陣,x3x 9x.3j x 2x6x 18x.2i x 2i 3jx 可以發現,滿足要求的子集...