郑厂长系列故事——排兵布阵

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1509    Accepted Submission(s): 554


Problem Description
  郑厂长不是正厂长
  也不是副厂长
  他根本就不是厂长
  事实上
  他是带兵打仗的团长

  一天,郑厂长带着他的军队来到了一个n*m的平原准备布阵。
  根据以往的战斗经验,每个士兵可以攻击到并且只能攻击到与之曼哈顿距离为2的位置以及士兵本身所在的位置。当然,一个士兵不能站在另外一个士兵所能攻击到的位置,同时因为地形的原因平原上也不是每一个位置都可以安排士兵。
  现在,已知n,m 以及平原阵地的具体地形,请你帮助郑厂长计算该阵地,最多能安排多少个士兵。
 

 

Input
输入包含多组测试数据;
每组数据的第一行包含2个整数n和m (n <= 100, m <= 10 ),之间用空格隔开;
接下来的n行,每行m个数,表示n*m的矩形阵地,其中1表示该位置可以安排士兵,0表示该地形不允许安排士兵。
 

 

Output
请为每组数据计算并输出最多能安排的士兵数量,每组数据输出一行。
 

 

Sample Input
6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 

 

Sample Output
2

 

 

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <math.h>
  5 #include <algorithm>
  6 using namespace std;
  7 int a[2][170],n,m,zh,b[100],dp[2][170][170];
  8 bool check(int x,int y)
  9 {
 10     int x1=x<<1,x2=x>>1;
 11     if(y&x1)return 0;
 12     if(y&x2)return 0;
 13     return 1;
 14 }
 15 bool check1(int x,int y)
 16 {
 17     if(x&y)return 0;
 18     return 1;
 19 }
 20 bool check2(int x,int y)
 21 {
 22     int z=x|y;
 23     if(z>y)return 0;
 24     return 1;
 25 }
 26 int fun(int x)
 27 {
 28     int s=0;
 29     while(x)
 30     {
 31         s+=x&1;
 32         x>>=1;
 33     }
 34     return s;
 35 }
 36 void init()
 37 {
 38     zh=0;
 39     for(int i=0; i<(1<<m); i++)
 40     {
 41         if(!(i&(i<<2)))
 42         {
 43             a[0][zh]=i;
 44             a[1][zh++]=fun(i);
 45         }
 46     }
 47 }
 48 int main()
 49 {
 50 
 51     while(~scanf("%d%d",&n,&m))
 52     {
 53         init();
 54         int i,j,x,k,r;
 55         memset(dp,0,sizeof(dp));
 56         x=getchar();
 57         for(i=0; i<n; i++)
 58         {
 59             b[i]=0;
 60             for(j=0; j<m; j++)
 61             {
 62                 x=getchar();
 63                 b[i]=(b[i]<<1)+x-'0';
 64                 x=getchar();
 65             }
 66         }
 67         int ix,iy;
 68         for(i=0; i<n; i++)
 69         {
 70             ix=i&1,iy=!ix;
 71             for(j=0; j<zh; j++)
 72             {
 73                 if(check2(a[0][j],b[i]))
 74                     if(!i)
 75                     {
 76                         dp[0][0][j]=a[1][j];
 77                     }
 78                     else if(i==1)
 79                     {
 80                         for(k=0; k<zh; k++)
 81                         {
 82                             if(check(a[0][k],a[0][j]))
 83                                 dp[1][k][j]=dp[0][0][k]+a[1][j];
 84                         }
 85                     }
 86                     else
 87                     {
 88                         for(k=0; k<zh; k++)
 89                         {
 90                             if(check(a[0][k],a[0][j]))
 91                             {
 92                                 for(r=0; r<zh; r++)
 93                                 {
 94                                     if(check1(a[0][r],a[0][j]))
 95                                         dp[ix][k][j]=dp[ix][k][j]>dp[iy][r][k]+a[1][j]?dp[ix][k][j]:dp[iy][r][k]+a[1][j];
 96                                 }
 97                             }
 98 
 99                         }
100                     }
101             }
102         }
103         int sum=0;
104         for(i=0; i<zh; i++)
105             for(j=0; j<zh; j++)
106                 sum=sum>dp[ix][i][j]?sum:dp[ix][i][j];//,cout<<dp[1][i][j]<<" ";
107         printf("%d\n",sum);
108     }
109 }
View Code

 

posted on 2014-03-06 22:20  ERKE  阅读(274)  评论(0编辑  收藏  举报