• UVA-11795 Mega Man's Mission (状压DP)



    思路:

    • 求出每个状态i(已杀死机器人集合)能杀死的机器人数kill[i],即已死机器人的武器加上初始武器又能杀死的机器人的集合;
    • 每个状态i都只能往包含在kill[i]中,且不包含在s中的机器人j扩展,即i -> i|(1 << j);
    • dp[i]代表到达该状态的顺序总数,i等于所有前一个合法状态的和,易知dp[0] = 1,且只有从0状态扩展的状态才是合法的状态;

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 #define M(a) memset(a, 0, sizeof(a))
     5 #define INF 0x3f3f3f3f
     6 const int maxn = (1 << 16) + 10;
     7 int s[maxn], kill[maxn];
     8 long long dp[maxn];
     9 
    10 int main() {
    11 
    12     int T, n, kase = 0;
    13     scanf("%d", &T);
    14     while(T--) {
    15         char str[20];
    16         M(dp), M(kill), M(s);
    17         scanf("%d%s", &n, str);
    18         for (int i = 0; i < n; ++i)
    19             if (str[i] == '1')
    20                 kill[0] += (1 << i);
    21         for (int i = 0; i < n; ++i) {
    22             scanf("%s", str);
    23             for (int j = 0; j < n; ++j)
    24                 if (str[j] == '1') 
    25                     s[i] |= (1 << j);
    26         }
    27         int all = (1 << n) - 1;
    28         for (int i = 0; i <= all; ++i) {
    29             kill[i] = kill[0];
    30             for (int j = 0; j < n; ++j)
    31                 if (i & (1 << j))
    32                     kill[i] |= s[j];
    33         }
    34         dp[0] = 1;
    35         for (int i = 0; i < all; ++i)
    36             for (int j = 0; j < n; ++j)
    37                 if (((kill[i] & (1 << j))) && !(i & (1 << j)))
    38                     dp[i|(1 << j)] += dp[i];
    39         printf("Case %d: %lld
    ", ++kase, dp[all]);
    40     }
    41 
    42     return 0;
    43 }
  • 相关阅读:
    ubuntu16.04安装破解pycharm
    python解压,压缩,以及存数据库的相关操作
    cocoapods Error
    swift项目导入OC框架
    实现全屏滑动返回效果
    Storyboard & XIB 自己的理解
    View & Controller 一些方法的执行顺序
    Touch ID 实现
    Apple Pay 初探
    ReactiveCocoa学习
  • 原文地址:https://www.cnblogs.com/robin1998/p/6399660.html
Copyright © 2020-2023  润新知