hdu 5823 color II —— 子集DP

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5823

看博客:http://www.cnblogs.com/SilverNebula/p/5929550.html

学到了求子集中独立集的姿势~

还有那个子集DP真是太妙了!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int T,n,mp[20],f[1<<20],S,inf=0x3f3f3f3f;
bool inv[1<<20];
ll ans,mod=(1ll<<32);
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(mp,0,sizeof mp);
        memset(f,0,sizeof f);
        memset(inv,0,sizeof inv);
        scanf("%d",&n); S=(1<<n)-1;
        for(int i=0;i<n;i++)
            for(int j=0,x;j<n;j++)
            {
                scanf("%1d",&x);
                if(x)mp[i]|=(1<<j);
            }
        for(int s=1;s<=S;s++)
        {
            bool fl=0;
            for(int i=0;i<n;i++)
                if((s&(1<<i))&&(s&mp[i])){fl=1; break;}
            if(!fl)inv[s]=1;
        }
        for(int s=1;s<=S;s++)
        {
            int tmp=inf;
            for(int i=s;i;i=(i-1)&s)
                if(inv[i])tmp=min(tmp,f[s^i]+1);
            f[s]=tmp;
        }
        ll tmp=1; ans=0;
        for(int i=1;i<=S;i++)
        {
            tmp=(tmp*233)%mod;
            ans=(ans+f[i]*tmp)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2018-07-27 15:15  Zinn  阅读(143)  评论(0编辑  收藏  举报