UVA -11795 Mega Man's Mission(状态压缩DP)
题目链接:https://vjudge.net/problem/UVA-11795
题意:
你最初只有一个武器,你需要按照一定的顺序消灭n个机器人(n<=16)。每消灭一个机器人将会得到他的武器。
每个武器只能杀死特定的机器人,问可以消灭所有机器人的顺序方案总数。
AC代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int MAXN=(1<<16)+10; 6 int a[MAXN];// 保存每个机器人可以杀死的机器人 7 int b[MAXN];// 保存每个状态可以杀死的机器人 8 long long dp[MAXN]; 9 char s[20]; 10 int main(){ 11 int T,n,count=0; 12 scanf("%d",&T); 13 while(T--){ 14 memset(a,0,sizeof(a)); 15 memset(b,0,sizeof(b)); 16 memset(dp,0,sizeof(dp)); 17 scanf("%d",&n); 18 for(int i=0;i<=n;i++){ 19 scanf("%s",s); 20 for(int j=0;j<n;j++){ 21 if(s[j]=='1') 22 a[i]|=(1<<j); 23 //011表示可以杀死2号3号 ,6的二进制'110'含有1的位为2,3 24 } 25 } 26 int len=(1<<n)-1; 27 for(int i=0;i<=len;i++){//所有状态 28 b[i]=a[0]; 29 for(int j=1;j<=n;j++){ 30 int k=j-1; 31 if(i&(1<<k)) b[i]|=a[j]; 32 //如果该状态可以杀死j号,那么该状态也可以杀死j所能干掉的 33 } 34 } 35 dp[0]=1; 36 //当所有机器人都不杀死的方案总数为 1 , 即 dp[0] = 1 37 for(int i=1;i<=len;i++) 38 for(int j=1;j<=n;j++) 39 { 40 int k=j-1; 41 // 如果 i 的这种状态能够杀死 j 42 // 那么 i 由不能杀死 j 的状态转移过来 , 即i^(1<<k) 43 // 并且要求 i^(1<<k)这种状态要能够杀死j 44 if((i&(1<<k))&&(b[i^(1<<k)]&(1<<k))) 45 dp[i]+=dp[i^(1<<k)]; 46 } 47 printf("Case %d: %lld\n",++count,dp[len]); 48 } 49 }