codechef August Challenge 2014 第五个题目

来源:互联网 发布:ubuntu怎么配置ip 编辑:程序博客网 时间:2024/05/16 12:34

题意:点击打开链接

题目链接:点击打开链接

思路:入门的状态压缩,如果按照行一行一行下来(选衣服)去选的话状态太多,无法压缩,考虑到题目中n比较小,所以改用按照列一列一列推,把人压缩到二进制里面,1表示这个人已经选了,0表示还没有选,然后递推就可以达到答案!


#include<set>#include<queue>#include<cmath>#include<cstdio>#include<vector>#include<string>#include<utility>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define Inf (1<<30)#define LL long long#define MOD 1000000007#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int MM=100010;LL dp[1<<10];int n;int vis[11][101];void read(int x){    int res=0;    char ch;    do    {        ch=getchar();        if(ch==' '||ch=='\n')        {            vis[x][res-1]=1;            res=0;        }        else res=res*10+ch-'0';    }    while(ch!='\n');}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d\n",&n);        memset(dp,0,sizeof(dp));        memset(vis,0,sizeof(vis));        for(int i=0;i<n;i++)read(i);        dp[0]=1;        for(int i=0;i<100;i++)        {            for(int j=(1<<n)-1;j>=0;j--)//这里用到了一个优化空间的技巧,类似于01背包的空间优化,已经用了的空间可以覆盖掉,从后面开始递推就行了            {                if(dp[j]==0)continue;                for(int k=0;k<n;k++)                {                    if(vis[k][i]==0)continue;                    if(j&(1<<k))continue;                    dp[j|(1<<k)]+=dp[j];                    dp[j|(1<<k)]%=MOD;                }            }        }        printf("%lld\n",dp[(1<<n)-1]);    }    return 0;}


0 0
原创粉丝点击