POJ1185 炮兵阵地

题目大意:在一块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
",ans);
View Code
原文地址:https://www.cnblogs.com/hefenghhhh/p/4609973.html