There are two kinds of points for a map. You can stand at point P and cannot stand at point h. Each person put in a person will have an impact on the two grids above and down, and the grids that have an impact cannot be placed. Ask how many people can put at most.
Train of Thought: Data scope guides the problem-solving direction. M is given in the question <= 10, which is a small number. 2 ^ 10 is only 1024, so it is much easier to use DP. Therefore, we first pre-process the possible status of each row. Note that there cannot be two distances in one row <2. After a large table is created, it is found that each row can have a maximum of about 60 tables. Now you can do O (N ^ 3 × m) DP with confidence. When handling the relationship between the upper and lower rows, you must note that status & status _ = 0 can be transferred.
The final result is that if M is less than or equal to 2, you can directly find a maximum output value from the status.
Code:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int m,n;char src[110][110];int status[110][1500];int num[1500];int f[110][110][110];void Pretreatment(){for(int i = 1; i <= (1 << n); ++i)num[i] = num[i >> 1] + (i&1);}inline bool Judge(int x,int status){static bool v[110];memset(v,false,sizeof(v));int p = 0;while(status) {v[p++] = status&1;status >>= 1;}for(int i = 0; i < n; ++i)if(v[i]) {if(src[x][i] == 'H')return false;if(v[i - 1] || v[i - 2])return false;}return true;}int main(){cin >> m >> n;Pretreatment();for(int i = 1; i <= m; ++i)scanf("%s",src[i]);for(int i = 1; i <= m; ++i)for(int j = 0; j < (1 << n); ++j)if(Judge(i,j))status[i][++status[i][0]] = j;for(int j = 1; j <= status[2][0]; ++j)for(int i = 1; i <= status[1][0]; ++i)if((status[1][i]&status[2][j]) == 0)f[2][j][i] = max(f[2][j][i],num[status[1][i]] + num[status[2][j]]);if(m == 1 || m == 2) {int ans = 0;for(int i = 1; i <= status[1][0]; ++i)ans = max(ans,num[status[1][i]]);for(int i = 1; i <= status[2][0]; ++i)ans = max(ans,num[status[2][i]]);cout << ans << endl;return 0;}int ans = 0;for(int i = 3; i <= m; ++i)for(int j = 1; j <= status[i][0]; ++j)for(int k = 1; k <= status[i - 1][0]; ++k)for(int l = 1; l <= status[i - 2][0]; ++l) {if((status[i][j]&status[i - 1][k]) || (status[i - 1][k]&status[i - 2][l]) || (status[i][j]&status[i - 2][l]))continue;f[i][j][k] = max(f[i][j][k],f[i - 1][k][l] + num[status[i][j]]);ans = max(ans,f[i][j][k]);}cout << ans << endl;return 0;}
Poj 1185 Noi 2001 Artillery Position pressure DP