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\n",ans);
View Code

 

你可能感兴趣的:(poj)