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 } 
View Code

 

posted @ 2018-09-04 20:15  ccsu_dj辉  阅读(116)  评论(0编辑  收藏  举报