定義乙個非空集合是合法的,當且僅當它滿足以下兩個條件。
1、集合內所有元素and和為0
2、它的非空子集中僅有它本身滿足1
給出乙個集合s,求它的合法非空子集數。
第一行乙個正整數n,表示|s|
第二行n個非負整數ai,表示集合內的元素。
n≤1000,ai<1024
乙個整數,表示s的合法非空子集數。答案可能很大,請mod 1e9+7之後輸出。
1 2 4 4
樣例解釋:滿足條件的集合為,,,,
**棟爺的部落格
先把給定集合所有數取反。
比如有效位數是4位,1101就變成0010。
那麼問題變成,所有元素or和為1023,而去掉任意乙個元素後or和均不為1023。
那麼接下來我們來設乙個詭異的狀態。
因為要知道去掉乙個人元素會不會使or和為1023,因此我們前後都要知道。
可以設乙個f[i,j,k]表示做完了i個數,前面選擇的一些數or和為j,我們希望後面選出的數or和為k。
然而隨便推一推都覺得不會轉移啊。。
這時趕緊改一下狀態,設f[i,j,k]表示做完了i個數,前面選擇的一些數or和為j,我們希望後面選出的數or和包含k(什麼叫包含?x包含k需滿足x&k=k)
設第i+1個數為x。
不選?
f[i+1][j][k]+=f[i][j][k]
選呢?
假設後面部分不包含x時是k』。
我們發現k』需要滿足兩個條件:
1、k』|x=k(根據狀態定義)
2、k』|j|x!=k』|j(如果等了那麼就能去掉x了)
滿足條件的k』肯定存在一些包含關係,而我麼的狀態設的也是包含,所以轉移會比較方便。
先只考慮滿足第乙個條件:
f[i+1][j|x][k^(k&x)]+=f[i][j][k]
這個很容易考慮,如果k的某一位有1,x該位也有1,那麼k』的這一位可以是0也可以為1。
再去掉滿足第乙個條件而不滿足第二個條件的:
f[i+1][j|x][(k^(k&x))|(x^(x&j))]-=f[i][j][k]
這是個什麼意思?先看後面,顯然只有x的某一位是1,而j的對應位是0時才有1的貢獻,意思就是x會給j的哪些原本沒有1的位變成1。
而如果k』的這些位也有1,那麼j|k』後,再或x將不變,因此會不滿足第二個條件。
然後這個dp就是正確的,初始f[0][0][0]=1,最後答案是f[n][1023][0]。
假設有m位,這樣做是n∗4^m
考慮優化吧。我們來證明,如果f[i][j][k]不為0,一定有j包含k。
初始時顯然滿足。
看第一條轉移,f[i+1][j|x][k^(k&x)]+=f[i][j][k]。
假如j包含k,k的某位為0時,k&x的對應位肯定也是0,所以k^(k&x)並不會多1,反而可能少1,但j|x不會少1,因此有j|x包含k^(k&x)。
看第二條轉移,f[i+1][j|x][(k^(k&x))|(x^(x&j))]-=f[i][j][k]。
假如j包含k,記k』=k^(k&x)。假如k』某位為1,可以不管它,由上面的結論j|x的這位也會是1。假如k某位為0,k』這位也是0,而x^(x&j)是1,那麼最終這位會是1,而因為x^(x&j)的這位是1,x這位必須是1,那麼j|x這位也有1了。
這樣列舉j後每次只需列舉乙個j包含的k,有個快捷的列舉方法見**。
那麼可以證明複雜度降為
n∗3^m
#include
#define n 1030
#define mod 1000000007
using
namespace
std;
int n;
int f[2][n][n], tmp;
void add(int &t, int d)
int main()
for (int j = 0; j < 1024; ++ j)
add(f[tmp][0][j], f[!tmp][0][j]);
add(f[tmp][0][j & d], f[!tmp][0][j]);
add(f[tmp][0][j & (0 | d)], mod - f[!tmp][0][j]);}}
printf("%d", f[tmp][0][0]);
}
EXT 最小集合
想把ext放入自己的專案,需要自己整理一下,因為發布包裡的東西並非都是必要的,比如文件,比如例子,比如源 必要的最小集合是這樣 ext all.js,adapter ext ext base.js,build locale ext lang zh cn.js和整個resources目錄。ext al...
51nod 最小集合
最小集合 system message 命題人 基準時間限制 1 秒 空間限制 131072 kb 分值 80 a君有乙個集合。這個集合有個神奇的性質。若x,y屬於該集合,那麼x與y的最大公因數也屬於該集合。但是他忘了這個集合中原先有哪些數字。不過幸運的是,他記起了其中n個數字。當然,或許會因為過度...
51nod 1616 最小集合
原題鏈結 1616 最小集合 基準時間限制 1 秒 空間限制 131072 kb 分值 80 難度 5級演算法題 a君有乙個集合。這個集合有個神奇的性質。若x,y屬於該集合,那麼x與y的最大公因數也屬於該集合。但是他忘了這個集合中原先有哪些數字。不過幸運的是,他記起了其中n個數字。當然,或許會因為過...