标签:
题目大意:在一块N*M的区域内,P为平原,H为山地。平原可以放炮兵部队,山地不可以。每支炮兵部队可能会误伤同行或同列【-2,+2】区间内的友军。在保证不误伤的前提下,问该区域最多可以布置多少炮兵。N<=100,M<10
分析:按行处理。每一行的状态可以用dfs处理出来,保存在数组中。
f[i][j][k]=∑(f[[i-1][k][p])
f[i][j][k]表示第i行的状态为j且上一行的状态为k时最多能布置的炮兵数。
j与k不能冲突,j与p也不能冲突,k与p不能冲突。f初始值为0.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<cstring> 6 using namespace std; 7 #define MAXN 105 8 int f[MAXN][MAXN][MAXN],n,m,state[MAXN][MAXN],row,cnt,cnts[MAXN][MAXN],nums[MAXN],num; 9 char arr[MAXN][MAXN]; 10 void dfs(int j,int sta,int cnt) 11 { 12 if(j>m) 13 { 14 state[row][num++]=sta; 15 cnts[row][num-1]=cnt; 16 nums[row]=num; 17 return; 18 } 19 if((sta&3)==0&&arr[row][j]==‘P‘) 20 dfs(j+1,(sta<<1)+1,cnt+1); 21 dfs(j+1,(sta<<1),cnt); 22 } 23 int main() 24 { 25 scanf("%d%d",&n,&m); 26 for(int i=1;i<=n;i++) 27 {scanf("%s",arr[i]+1); 28 row=i; 29 num=0; 30 dfs(1,0,0); 31 } 32 memset(f,0,sizeof f); 33 for(int i=0;i<nums[1];i++) 34 f[1][i][0]=cnts[1][i]; 35 nums[0]=1; 36 for(int i=2;i<=n;i++) 37 for(int j=0;j<nums[i];j++) 38 for(int k=0;k<nums[i-1];k++) 39 if((state[i][j]&state[i-1][k])==0) 40 { 41 for(int q=0;q<nums[i-2];q++) 42 { 43 if((state[i-1][k]&state[i-2][q])==0&&(state[i][j]&state[i-2][q])==0) 44 if(f[i][j][k]<f[i-1][k][q]+cnts[i][j]) 45 f[i][j][k]=f[i-1][k][q]+cnts[i][j]; 46 } 47 } 48 long long ans=0; 49 for(int i=0;i<nums[n];i++) 50 for(int j=0;j<nums[n-1];j++) 51 if(ans<f[n][i][j]) 52 ans=f[n][i][j]; 53 printf("%I64d\n",ans);
标签:
原文地址:http://www.cnblogs.com/hefenghhhh/p/4609973.html