您的位置:首页 > 其它

uva11795

2016-04-19 20:10 295 查看
题目大意:

给出有几个怪兽以及初始的可以打的怪兽的二进制序列。为1的就是可以打的为0的就是不可以打的。

打死一只怪兽后你就可以用它的武器去打特定的怪兽。

问最多有几种方案。

思路:

状态压缩DP。

S[i]表示的是当死的怪兽的状态为i的时候所获得的武器可以打死哪些怪兽。

weapon[i]表示当打死怪兽i的时候所可以获得的武器。

dp[i]表示当死的怪兽的状态为i的时候最多可以有几种方案。

代码:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
const int MAX = 65550;

int S[MAX];
long long dp[MAX];
int weapon[18];
char robot[18];
char initial[18];

int main() {

int T;
int n;
scanf("%d",&T);
int kase = 0;
while(T--) {
scanf("%d %s",&n,initial);
memset(S,0,sizeof(S));
memset(weapon,0,sizeof(weapon));
memset(dp,0,sizeof(dp));

for(int i = 0; i < strlen(initial); i++) {
if(initial[i] == '1')
S[0] |=(1 << i);
}
for(int i = 0; i < n; i++) {
scanf("%s",robot);
for(int j = 0; j < strlen(robot); j++)
if(robot[j] == '1')
weapon[i] |= (1 << j);
}
for(int i = 0; i < (1 << n); i++) {
S[i] = S[0];
for(int j = 0; j < n ; j++) {
if((i & (1 << j)))
S[i] |= weapon[j];
}
}
dp[0] = 1;
for(int i = 0; i < (1 << n); i++) {
if(dp[i] == 0)
continue;
for(int j = 0;j < n; j++) {
if((S[i] &(1 << j))!= 0 && (i &(1 << j)) == 0)
dp[i | (1 << j)] += dp[i];
}
}
printf("Case %d: %lld\n", ++ kase,dp[(1 << n) - 1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: