UVA 11795 Mega Man's Mission 状态DP

 状态DP,设S为当前已经获得的武器的集合,预处理全部S能攻击的集合g[S]。

 后面的状态转移就是

dp[st]=sum{dp[st^(1<<i)] | i为st的元素,且i为个g[st^(1<<i)]的元素}

ll dp[1<<16];
int g[1<<16];
int n;
int p[20];
int read()
{
    char s[20][20];
    scanf("%d",&n);
    for(int i=0;i<=n;i++)
        scanf("%s",s[i]);
    for(int i=0;i<=n;i++)
    {
        p[i]=0;
        for(int j=0;j<n;j++)
            if(s[i][j]=='1')p[i]|=(1<<j);
    }
    int total=(1<<n)-1;
    for(int st=0;st<=total;st++)
    {
        g[st]=p[0];
        for(int i=1;i<=n;i++)
        {
            int j=i-1;
            if(st&(1<<j))g[st]|=p[i];
        }
    }
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int ca=1;ca<=t;ca++)
    {
        read();
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        int total=(1<<n)-1;
        for(int st=1;st<=total;st++)
        {
            for(int i=0;i<n;i++)if(st&(1<<i))
            {
                if(g[st^(1<<i)]&(1<<i))
                    dp[st]+=dp[st^(1<<i)];
            }
        }
        printf("Case %d: %lld
",ca,dp[total]);

    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/BMan/p/3252832.html