Artillery Position Time Limit: 2000 MS | memory limit: 65535 kb difficulty: 6
-
-
Description
-
The generals of the Headquarters intend to deploy their artillery troops on the grid map of N * m. A n * m map consists of N rows and M columns. Each grid of the map may be a mountain (represented by "H") or a plain (represented by "p ), for example. A maximum of one artillery unit can be deployed on each plain terrain (the artillery unit cannot be deployed on the mountain). The black area of an artillery unit in the attack range on the map is shown:
If an artillery force is deployed on the gray plain marked by the map, the Black Grid in the figure indicates the area to which it can attack: two grids along the horizontal left and right, the two cells are vertical and vertical. No other white mesh attacks can be found on the graph. The artillery attack range is not affected by the terrain.
Now, the generals plan how to deploy artillery troops to prevent accidental injuries (ensure that no two artillery troops can attack each other, that is, no artillery force is within the attack scope of other Artillery Forces.) the maximum number of Artillery Troops in our army can be placed in the whole map area.
-
-
Input
-
-
Number of output data test groups in the first row x (0 <x <100)
The first row of each group of test data contains two positive integers separated by spaces, representing N and m, respectively. The next n rows, each row contains M consecutive characters ('P' or 'H') with no spaces in the middle. Represent the data of each row in the map in order. 0 <= n <= 100; 0 <= m <= 10.
-
-
Output
-
-
Each group of test data outputs only one row, containing an integer k, indicating the maximum number of artillery troops that can be placed.
-
-
Sample Input
-
-
15 4. phpppphhppphppphhp
-
-
Sample output
-
-
6
Analysis: DP [I] [J] [k] indicates to arrange to row I, the state of the row I-1 is s [J], the maximum number of artillery lines that can be placed when the state of the I-2 row is s [K.
Then DP [I] [J] [k] = max (DP [I] [J] [K], DP [I-1] [J] [k] + num [I]). The first and second rows are specially processed.
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 105;int Map[N];int dp[N][65][65]; //dp[i][j][k]表示放第i行时,第i-1行为第j个状态,第i-2行为第k个状态最多可以放多少个炮兵int s[N], num[N];int n, m, p;bool check(int x) { //判断本行的炮兵是否互相攻击 if(x & (x >> 1)) return false; if(x & (x >> 2)) return false; return true;}int Count(int x) { //计算状态为x时可以放多少个炮兵 int i = 1, ans = 0; while(i <= x) { if(x & i) ans++; i <<= 1; } return ans;}void Init() { p = 0; memset(s, 0, sizeof(s)); memset(num, 0, sizeof(num)); for(int i = 0; i < (1 << m); i++) { //预处理出合法状态 if(check(i)) { s[p] = i; num[p++] = Count(i); } }}int main() { char ch; int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); if(!n && !m) { printf("0\n"); continue; } memset(dp, 0, sizeof(dp)); memset(Map, 0, sizeof(Map)); for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { cin >> ch; if(ch == 'H') Map[i] = Map[i] | (1 << (m - 1 - j)); //P为0,H为1 } } Init();// printf("p = %d\n", p);// for(int i = 0; i < p; i++) {// printf("s[%d] = %d, num[%d] = %d\n", i, s[i], i, num[i]);// } for(int i = 0; i < p; i++) { //求第一行最多放多少 if(!(Map[0] & s[i])) dp[0][i][0] = num[i]; } for(int i = 0; i < p; i++) { //前两行最多放多少 if(!(Map[1] & s[i])) { for(int j = 0; j < p; j++) { if((!(s[i] & s[j]))) { dp[1][i][j] = max(dp[1][i][j], dp[0][j][0] + num[i]); } } } } for(int r = 2; r < n; r++) { //枚举行数 for(int i = 0; i < p; i++) { //当前行的状态 if(!(s[i] & Map[r])) { for(int j = 0; j < p; j++) { //上一行的状态 if(!(s[j] & Map[r-1])) { if(!(s[i] & s[j])) { for(int k = 0; k < p; k++) { //上上一行的状态 if(!(s[k] & Map[r-2])) { if(!(s[j] & s[k])) { if(!(s[i] & s[k])) { dp[r][i][j] = max(dp[r][i][j], dp[r-1][j][k] + num[i]); } } } } } } } } } } int ans = 0; for(int i = 0; i < p; i++) { for(int j = 0; j < p; j++) { if(ans < dp[n-1][i][j]) ans = dp[n-1][i][j]; } } printf("%d\n", ans); } return 0;}
Poj 1185 & nyoj 85 artillery position (State compression DP)