标签:水题
题意就不对说了; 开始想用深搜过 感觉数据水的话应该能过, 哈哈 还是超时了!!!
正确做法应该是状态压缩吧,n小于等于17 2^17-1种状态,每种状态表示对应的数用没用过,如果用状态压缩dp的思路(从小状态跑到大状态)的话就不对了,开始一直没想明白,仔细想想也是,如果按以前的 就会改变dp里面的值,实际上对每一种状态的值是一定的,还有就是为什么要跑结果的对立面,看看测试数据 ,两个要求之间是有重复的,比如1,1和2,2 这样跑起来就不方便。 跑的时候三重for 外层枚举每个位置就行
#include<string.h> #include<iostream> using namespace std; __int64 has[20],dp[1<<18]; int deal() { has[0]=1; for(int i=1;i<=17;i++) { has[i]=has[i-1]*i; //printf("%I64d\n",hash[i]); } return 0; } int main() { int T,i,j,n,m,d=1; int map[20][20]; deal(); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(map,0,sizeof(map)); for(i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); map[a-1][b-1]=1; } memset(dp,0,sizeof(dp)); int x=1<<n; dp[0]=1; for(i=0;i<n;i++) { for(j=x-1;j>=0;j--) { if(!dp[j]) continue; for(int k=0;k<n;k++) { if(j&(1<<k)) continue; if(map[i][k]) continue; dp[j|(1<<k)]+=dp[j]; } } } printf("Case %d: %I64d\n",d++,has[n]-dp[x-1]); } return 0; }
标签:水题
原文地址:http://blog.csdn.net/zxf654073270/article/details/45287731