本文共 2799 字,大约阅读时间需要 9 分钟。
司令部的将军们打算在N * M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:
第一行包含两个由空格分割开的正整数,分别表示N和M;
接下来的N行,每一行含有连续的M个字符(‘P’或者’H’),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。
5 4
PHPP PPHH PPPP PHPP PHHP
6
1 1
P 1 1 H 12 9 HPHHPHHPH PPPHHPPHP HHPHHHHPP PHHHHPHHP HHHPHPHHH HPHPPPPPP PPPHHPPPP HPHPHHHPH PPHPPPHPH PHPHPPPHP HPHHPHHPH HPPPHHPHH
1
0 25
#includeusing namespace std;typedef long long ll;#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);const int mod = 1e9;int f[101];int dp[101][70][70]; // 第 i 行,状态为 j,i-1行状态为 k 时候的最大价值int state[70];int num[70]; // 每种状态 1 的个数int cnt;int main() { ios; int n, m; while (cin >> n >> m) { cnt = 0; memset(dp, 0, sizeof(dp)); for (int i = 0; i < 1 << m; ++i) { if (!(i & i << 2) && !(i & i << 1)) state[cnt] = i; else continue; int j = 0; int temp = i; for (j = 0; temp; ++j) temp &= (temp - 1); // 去掉最低位的 1 num[cnt++] = j; } for (int i = 1; i <= n; ++i) { string str; cin >> str; int sum = 0; for (int j = 0; j < m; ++j) { if (str[j] == 'P') // 1 :平原, 0 :山 sum = sum << 1 | 1; else sum = sum << 1; } f[i] = sum; } for (int i = 0; i < cnt; i++) { if (!(state[i] & f[1])) continue; dp[1][i][0] = num[i]; // 第 1 行初始化 } for (int i = 2; i <= n; ++i) { // 第 i 行 for (int j = 0; j < cnt; ++j) { // 枚举当前行状态 j if ((state[j] & f[i]) == state[j]) { for (int k = 0; k < cnt; ++k) { // 枚举上一行状态 if ((state[k] & f[i - 1]) == state[k] && !(state[j] & state[k])) for (int t = 0; t < cnt; ++t) { if ((state[t] & f[i - 2]) == state[t] && !(state[j] & state[t]) && !(state[k] & state[t])) dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][t] + num[j]); } } } } } int ans = 0; for (int i = 0; i < cnt; ++i) { for (int j = 0; j < cnt; ++j) { ans = max(ans, dp[n][i][j]); } } cout << ans << endl; }}
转载地址:http://chcjz.baihongyu.com/