hdu3006 状态压缩+位运算+hash(小想法题)
生活随笔
收集整理的這篇文章主要介紹了
hdu3006 状态压缩+位运算+hash(小想法题)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? ?給了n個集合,問你這n個集合可以組合出多少種集合,可以自己,也可以兩個,也可以三個....也可以n個集合組在一起。
tmp = 0;
for(i ,1 - k) scanf(num) ,tmp = tmp | (1 << (num - 1));
hash[tmp] = 1;標記上當前的這個集合是可以得到的。
這樣最后的這個tmp就是當前的這個集合壓縮后的數,然后我們在枚舉之前的所有可能狀態,得到新的可能狀態(其實就是簡單dp)
for(i = 1 ;i < 1 << 14 ;i ++) if(hash[i]) ans++;
? ? ? ?給了n個集合,問你這n個集合可以組合出多少種集合,可以自己,也可以兩個,也可以三個....也可以n個集合組在一起。
思路:
? ? ? 是個小想法題目,要用到二進制壓縮,位運算,還有hash,這4樣加起來說明這個題目真的很不錯,不廢話,首先對于每個集合有k個元素,每個元素都是不大于14的,那么我們可以二進制壓縮,把每個集合壓縮成一個二進制數,壓縮過程設計到位運算對于每個集合tmp = 0;
for(i ,1 - k) scanf(num) ,tmp = tmp | (1 << (num - 1));
hash[tmp] = 1;標記上當前的這個集合是可以得到的。
這樣最后的這個tmp就是當前的這個集合壓縮后的數,然后我們在枚舉之前的所有可能狀態,得到新的可能狀態(其實就是簡單dp)
for(i = 1 ;i < 1 << 14 ;i ++) if(hash[i]) hash[i|tmp] = 1; 之前的可能情況加上當
前的可能情況也是可能情況。最后在統計下可能情況的個數就ok了,for(i = 1 ;i < 1 << 14 ;i ++) if(hash[i]) ans++;
做這個題目的時候sb了,開了個 hash[1<<13+1] 哎! 1<<13+1 != 1 << 14 - 1.
#include<stdio.h> #include<string.h> int hash[1 << 14];int main () {int n ,m ,i ,j ,k ,num ,tmp ,ans;while(~scanf("%d %d" ,&n ,&m)){memset(hash ,0 ,sizeof(hash));for(i = 1 ;i <= n ;i ++){scanf("%d" ,&k);tmp = 0;for(j = 1 ;j <= k ;j ++)scanf("%d" ,&num) ,tmp = tmp | (1 << (num - 1));hash[tmp] = 1;for(j = 0 ;j < 1 << 14 ;j ++)if(hash[j]) hash[tmp | j] = 1;}ans = 0;for(i = 0 ;i < 1 << 14 ;i ++)if(hash[i]) ans ++;printf("%d\n" ,ans);}return 0; }
總結
以上是生活随笔為你收集整理的hdu3006 状态压缩+位运算+hash(小想法题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu2056 矩形重叠面积(水题)
- 下一篇: hdu4530 水题