Artillery positions
Time Limit: 2000 MS Memory Limit: 65536 K
Total Submissions: 16003 Accepted: 6077
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 (artillery units cannot be deployed on mountains );
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
The first line contains two positive integers separated by spaces, representing N and M respectively;
In 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. N <= 100; M <= 10.
Output
Only one row contains an integer K, indicating the maximum number of artillery troops that can be placed.
Sample Input
5 4
PHPP
PPHH
PPPP
PHPP
PHHPSample Output
6 Source
Noi 01
Dp [I] [j] [u] = Max + sum [I] [j];
Max = max (Max, dp [I-1] [u] [v]); // don't forget this because it's wrong many times
#include <iostream> #include <cstdio> #include <cstring> #define N 110 #define M 65 using namespace std; int dp[N][M][M],b[M],sum[N][M],n,m; char s1[M]; bool a[N][M],status[N][M]; int main() { //freopen("data.in","r",stdin); bool check(int k); int get_sum(int i,int j); while(scanf("%d %d",&n,&m)!=EOF) { memset(a,true,sizeof(a)); for(int i=1;i<=n;i++) { scanf("%s",s1); for(int j=1;j<=m;j++) { if(s1[j-1]=='H') { a[i][j] = false; } } } int Top=0; for(int i=0;i<(1<<m);i++) { bool k = check(i); if(k) { b[Top++] = i; } } memset(sum,0,sizeof(sum)); memset(status,true,sizeof(status)); for(int i=1;i<=n;i++) { for(int j=0;j<=Top-1;j++) { sum[i][j] = get_sum(i,j); } } memset(dp,0,sizeof(dp)); int res = 0; for(int i=0;i<=Top-1;i++) { if(!status[1][i]) { continue; } for(int j=0;j<=Top-1;j++) { if((b[i]&b[j])==0) { dp[1][i][j] = sum[1][i]; res = max(res,dp[1][i][j]); } } } for(int i=2;i<=n;i++) { for(int j=0;j<=Top-1;j++) { if(!status[i][j]) { continue; } for(int u=0;u<=Top-1;u++) { if(!status[i-1][u]||(b[j]&b[u])!=0) { continue; } int Max = 0; for(int v=0;v<=Top-1;v++) { if(!status[i-2][v]||(b[v]&b[u])!=0||(b[v]&b[j])!=0) { continue; } Max = max(Max,dp[i-1][u][v]); } dp[i][j][u] = Max+sum[i][j]; res = max(res,dp[i][j][u]); } } } printf("%d\n",res); } return 0; } bool check(int k) { int w[M]; memset(w,0,sizeof(w)); for(int i=1;i<=m;i++) { w[i] = k&1; k=k>>1; } for(int i=1;i<=m;) { if(w[i]==0) { i++; continue; } if(w[i]==1&&w[i+1]==0&&w[i+2]==0) { i+=2; }else { return false; } } return true; } int get_sum(int i,int j) { int k = b[j],s=0; bool check1=true;; for(int x=1;x<=m;x++) { int y = k&1; k=k>>1; if(y==1&&!a[i][x]) { check1 = false; break; }else if(y==1&&a[i][x]) { s++; } } if(!check1) { status[i][j] = false; s=0; } return s; } #include <iostream>#include <cstdio>#include <cstring>#define N 110#define M 65using namespace std;int dp[N][M][M],b[M],sum[N][M],n,m;char s1[M];bool a[N][M],status[N][M];int main(){ //freopen("data.in","r",stdin); bool check(int k); int get_sum(int i,int j); while(scanf("%d %d",&n,&m)!=EOF) { memset(a,true,sizeof(a)); for(int i=1;i<=n;i++) { scanf("%s",s1); for(int j=1;j<=m;j++) { if(s1[j-1]=='H') { a[i][j] = false; } } } int Top=0; for(int i=0;i<(1<<m);i++) { bool k = check(i); if(k) { b[Top++] = i; } } memset(sum,0,sizeof(sum)); memset(status,true,sizeof(status)); for(int i=1;i<=n;i++) { for(int j=0;j<=Top-1;j++) { sum[i][j] = get_sum(i,j); } } memset(dp,0,sizeof(dp)); int res = 0; for(int i=0;i<=Top-1;i++) { if(!status[1][i]) { continue; } for(int j=0;j<=Top-1;j++) { if((b[i]&b[j])==0) { dp[1][i][j] = sum[1][i]; res = max(res,dp[1][i][j]); } } } for(int i=2;i<=n;i++) { for(int j=0;j<=Top-1;j++) { if(!status[i][j]) { continue; } for(int u=0;u<=Top-1;u++) { if(!status[i-1][u]||(b[j]&b[u])!=0) { continue; } int Max = 0; for(int v=0;v<=Top-1;v++) { if(!status[i-2][v]||(b[v]&b[u])!=0||(b[v]&b[j])!=0) { continue; } Max = max(Max,dp[i-1][u][v]); } dp[i][j][u] = Max+sum[i][j]; res = max(res,dp[i][j][u]); } } } printf("%d\n",res); } return 0;}bool check(int k){ int w[M]; memset(w,0,sizeof(w)); for(int i=1;i<=m;i++) { w[i] = k&1; k=k>>1; } for(int i=1;i<=m;) { if(w[i]==0) { i++; continue; } if(w[i]==1&&w[i+1]==0&&w[i+2]==0) { i+=2; }else { return false; } } return true;}int get_sum(int i,int j){ int k = b[j],s=0; bool check1=true;; for(int x=1;x<=m;x++) { int y = k&1; k=k>>1; if(y==1&&!a[i][x]) { check1 = false; break; }else if(y==1&&a[i][x]) { s++; } } if(!check1) { status[i][j] = false; s=0; } return s;}