GHOJ 328 杀怪物

题目描述

  为了庆祝自己的生日,小张推出一款游戏。游戏在一个20×20的方格上进行,上面有一些怪物,用“#”表示,其他是空格,用“.”表示。怪物有两点体力。体力为0时死亡。

  你可以进行以下操作:

  (1)使一个横行上的怪物体力减一

  (2)使一个竖行上的怪物体力减一

  对每个横行或竖行只能操作一次,限定n次,问最多能杀死多少个怪物。

输入格式

  第一行为整数n(1≤n≤40),表示操作的次数。

  接下来是一个20×20的方格,“#”表示怪物,“.”表示空格。

输出格式

  一行,输出最多能杀死的怪物数量。

 

输入样例一

3
....................
....................
..###...............
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................

输出样例一

2

输入样例二

10 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 
#################### 

输出样例二

25

题解

  容易想到,如果想杀$(i,j)$的怪物,必须对第$i$行和第$j$列做操作。

  那么我们可以对行操作进行搜索,这样就可以得到当前情况下每列进行操作能杀死的怪物。

  我们用$c[i]$表示当前第$i$列进行操作后能杀死的怪物数量。排序一下选取最大值就好了。

  容易想到$c[i]$很小,实际上我么用计数排序会更快。

#include <iostream>

using namespace std;

const int n = 20;
int m;
int a[25][25];
int c[25];
int ans;

void DFS(int x, int cnt)
{
    if(cnt >= m) return;
    int t[25] = {0}, tot = 0, tmp = m - cnt;
    for(register int i = 1; i <= n; ++i)
    {
        ++t[c[i]];
    }
    for(register int i = n; i && tmp; --i)
    {
        if(t[i] <= tmp)
        {
            tot += t[i] * i;
            tmp -= t[i];
        }
        else
        {
            tot += tmp * i;
            tmp = 0;
        }
    }
    ans = max(ans, tot);
    for(register int i = x; i <= n; ++i)
    {
        for(register int j = 1; j <= n; ++j)
        {
            if(a[i][j]) ++c[j];
        }
        DFS(i + 1, cnt + 1);
        for(register int j = 1; j <= n; ++j)
        {
            if(a[i][j]) --c[j];
        }
    }
    return;
}

int main()
{
    cin >> m;
    char ch;
    for(register int i = 1; i <= n; ++i)
    {
        for(register int j = 1; j <= n; ++j)
        {
            cin >> ch;
            a[i][j] = ch == '#';
        }
    }
    DFS(1, 0);
    cout << ans;
    return 0;
}
参考程序
原文地址:https://www.cnblogs.com/kcn999/p/10702496.html