zoukankan      html  css  js  c++  java
  • Codeforces Gym101246C:Explode 'Em All(DP + bitset)

    http://codeforces.com/gym/101246/problem/C

    题意:给出一个n*m的图,“*”表示这个地方需要炸掉,炸弹可以如果丢在(i,j)位置的话,那么可以炸掉第i行第j列的所有“*”。问最少需要丢多少个炸弹可以使得所有“*”被炸掉。

    思路:一看就以为是个最小顶点覆盖。然后发现做不了。。。

    枚举行的状态i,1表示这一行不炸,0表示炸了这一行。

    然后递推。

    这里用bitset维护行的状态。

    f[i][j]表示第i行j列是否有“*”。

    dp[i]表示不炸的行状态有哪些列是需要炸的。

    num[i]表示不炸的行的数量。

    然后每个状态取最优。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define N 25
     4 char s[26];
     5 bitset<N> f[N], dp[1<<N];
     6 int id[1<<N], num[1<<N];
     7 
     8 int lowbit(int x) { return x & -x; }
     9 
    10 int main() {
    11     freopen("input.txt", "r", stdin);
    12     freopen("output.txt", "w", stdout);
    13     int n, m;
    14     scanf("%d%d", &n, &m);
    15     for(int i = 0; i < n; i++) {
    16         scanf("%s", s);
    17         for(int j = 0; j < m; j++) {
    18             f[i][j] = s[j] == '*';
    19         }
    20     }
    21     for(int i = 0; i < N; i++)
    22         id[1<<i] = i;
    23     int ans = max(n, m);
    24     for(int i = 1; i < (1 << n); i++) { // 状态i某一位是1表示这一位的行不炸
    25         dp[i] = dp[i-lowbit(i)] | f[id[lowbit(i)]]; // 状态i表示行的状态,1表示有'*',dp[i]表示没炸的行有多少列是需要炸的
    26         num[i] = num[i-lowbit(i)] + 1;  // 表示第i个状态不需要炸的行的数量
    27         ans = min(ans, max(n - num[i], (int)dp[i].count()));
    28         // n - num[i] 表示炸多少行, dp[i].count()表示炸多少列
    29     }
    30     printf("%d
    ", ans);
    31     return 0;
    32 }
  • 相关阅读:
    Word Ladder
    Word Ladder II
    Valid Palindrome
    java 正则表达式-忽略大小写与多行匹配
    Vue自定义指令
    定义格式化时间的全局过滤器
    Vue过滤器的使用
    daterangepicker 设置默认值为空(转载)
    js时间戳与日期格式之间的互转
    Vuedevtools安装
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6500610.html
Copyright © 2011-2022 走看看