[BZOJ 4057] Kingdoms
Link:
Solution:
一道比较基础的状压DP
看到$n<=20$,状态转移与顺序相关,就可以开心地状压了
1表示破产,0表示未破产,不断扩展破产的集合即可
Code:
#include <bits/stdc++.h> using namespace std; const int MAXN=105; int a[MAXN][MAXN],dp[1030*1030],T,n; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<(1<<n);i++) dp[i]=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&a[i][j]); dp[0]=1;bool f=false; for(int i=0;i<(1<<n);i++) if(dp[i]) for(int j=0;j<n;j++) if(!(i&(1<<j)) && !dp[i|(1<<j)]) { int tmp=0; for(int k=0;k<n;k++) if(!(i&(1<<k))) tmp+=a[j][k]; if(tmp>0) dp[i|(1<<j)]=1; } for(int i=0;i<n;i++) if(dp[((1<<n)-1)^(1<<i)]) f=true,printf("%d ",i+1); if(!f) putchar('0'); puts(""); } return 0; }