UVA11795 Mega Man's Mission 消灭妖怪(状压dp)

题意: 给出有几个怪兽以及初始的可以打的怪兽的二进制序列。为1的就是可以打的为0的就是不可以打的。 打死一只怪兽后你就可以用它的武器去打特定的怪兽。 问最多有几种方案。

分析:看数据大小估计是状压dp,S[i]表示的是当死的怪兽的状态为i的时候所获得的武器可以打死哪些怪兽。weapon[i]表示当打死怪兽i的时候所可以获得的武器。 dp[i]表示当死的怪兽的状态为i的时候最多可以有几种方案。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1<<17;

long long dp[N];
int S[N],weapon[18],T,n;
char robot[18],init[18];

int main() {
    scanf("%d",&T);
    int cas = 0;
    while(T--) {
        scanf("%d %s",&n,init);
        memset(S,0,sizeof(S));
        memset(weapon,0,sizeof(weapon));
        memset(dp,0,sizeof(dp));
        for(int i = 0; i < strlen(init); i++) {
            if(init[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", ++cas,dp[(1 << n) - 1]);
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值