状态压缩

来源:互联网 发布:英文写作润色软件 编辑:程序博客网 时间:2024/05/21 11:12

dp[i][j]  i表示用二进制表示有几个点如:5=101  表示0,2点存在1点不存在 题目中j表示存在点的时候奖励为多少。

if(i&(1<<j))

集点i包括点j

i=(i|(1<<j))

把点j加入到集点i中去

i=(i-(1<<j))

把点j从集点i中删去


//zcmu1552
#include<iostream>#include<algorithm>#include<cstring>#include<cmath>#include<cstdio>#include<string>#include<set>#include<map>#include<queue>#include<vector>#include<stack>using namespace std;#define ll long long#define cl(a,b) memset(a,b,sizeof(a))#define MAXN 100005int dp[4100][505];int a[15][15];int main(){    int t,n,m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        cl(dp,0);        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                scanf("%d",&a[i][j]);        dp[0][0]=1;        for(int i=0;i<(1<<n)-1;i++)        {            int sum=0;            for(int j=1;j<=n;j++)                if(i&(1<<(j-1)))sum++;            for(int j=1;j<=n;j++)            {                if(i&(1<<(j-1)))continue;                for(int k=0;k<=m;k++)                {                    if(k+a[sum+1][j]>=m)dp[i|(1<<(j-1))][m]+=dp[i][k];                    else dp[i|(1<<(j-1))][k+a[sum+1][j]]+=dp[i][k];                }            }        }        if(dp[(1<<n)-1][m])printf("%d\n",dp[(1<<n)-1][m]);        else printf("No solution\n");    }    return 0;}


0 0
原创粉丝点击