郑厂长系列故事——排兵布阵
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1338 Accepted Submission(s): 478
Problem Description
郑厂长不是正厂长
也不是副厂长
他根本就不是厂长
事实上
他是带兵打仗的团长
一天,郑厂长带着他的军队来到了一个n*m的平原准备布阵。
根据以往的战斗经验,每个士兵可以攻击到并且只能攻击到与之曼哈顿距离为2的位置以及士兵本身所在的位置。当然,一个士兵不能站在另外一个士兵所能攻击到的位置,同时因为地形的原因平原上也不是每一个位置都可以安排士兵。
现在,已知n,m 以及平原阵地的具体地形,请你帮助郑厂长计算该阵地,最多能安排多少个士兵。
也不是副厂长
他根本就不是厂长
事实上
他是带兵打仗的团长
一天,郑厂长带着他的军队来到了一个n*m的平原准备布阵。
根据以往的战斗经验,每个士兵可以攻击到并且只能攻击到与之曼哈顿距离为2的位置以及士兵本身所在的位置。当然,一个士兵不能站在另外一个士兵所能攻击到的位置,同时因为地形的原因平原上也不是每一个位置都可以安排士兵。
现在,已知n,m 以及平原阵地的具体地形,请你帮助郑厂长计算该阵地,最多能安排多少个士兵。
Input
输入包含多组测试数据;
每组数据的第一行包含2个整数n和m (n <= 100, m <= 10 ),之间用空格隔开;
接下来的n行,每行m个数,表示n*m的矩形阵地,其中1表示该位置可以安排士兵,0表示该地形不允许安排士兵。
每组数据的第一行包含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
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
Source
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 7 int state[170],Num[170],len; 8 int a[102]; 9 int befor[170][170],now[170][170]; 10 void Init() 11 { 12 int i,k=1<<10; 13 int ans,x; 14 len=0; 15 for(i=0;i<k;i++) 16 { 17 if( (i&(i<<2)) || (i&(i>>2)) ); 18 else{ 19 state[len]=i; 20 x=i; 21 ans=0; 22 while(x) 23 { 24 ans++; 25 x=(x-1)&x; 26 } 27 Num[len++]=ans; 28 } 29 } 30 } 31 void make_Init(int n,int m) 32 { 33 int i,j,k=1<<m; 34 int hxl; 35 memset(befor,0,sizeof(befor)); 36 memset(now,0,sizeof(now)); 37 if(n==1) 38 { 39 hxl=0; 40 for(i=0;i<len&&state[i]<k;i++) 41 { 42 if( (state[i]&a[1])==state[i] ) 43 if(hxl<Num[i]) 44 hxl=Num[i]; 45 } 46 printf("%d ",hxl); 47 return; 48 } 49 for(i=0,hxl=0;i<len&&state[i]<k;i++) 50 { 51 if( (state[i]&a[2])!=state[i] ) continue; 52 for(j=0,hxl=0;j<len&&state[j]<k;j++) 53 { 54 if( (state[j]&a[1])!=state[j] ) continue; 55 if( ((state[i]<<1)&state[j]) || ((state[i]>>1)&state[j]) ) continue; 56 befor[i][j]=Num[i]+Num[j]; 57 if(hxl<befor[i][j]) 58 hxl=befor[i][j]; 59 } 60 } 61 if(n==2) 62 { 63 printf("%d ",hxl); 64 } 65 } 66 void solve(int n,int m) 67 { 68 int i,j,k=1<<m; 69 int t,s,hxl; 70 make_Init(n,m); 71 if(n==1||n==2) return; 72 for(i=3;i<=n;i++) 73 { 74 for(j=0;j<len&&state[j]<k;j++) 75 { 76 if((state[j]&a[i])==state[j]) 77 for(s=0;s<len&&state[s]<k;s++) 78 { 79 if((state[s]&a[i-1])!=state[s]) continue; 80 if( ((state[j]<<1)&state[s]) || ((state[j]>>1)&state[s]) ) continue; 81 hxl=0; 82 for(t=0;t<len&&state[t]<k;t++) 83 { 84 if( (state[t]&a[i-2])!=state[t] ) continue; 85 if( (state[j]&state[t]) || ((state[s]<<1)&state[t]) || ((state[s]>>1)&state[t]) ) continue; 86 if(hxl<befor[s][t]) 87 hxl=befor[s][t]; 88 } 89 now[j][s]=hxl+Num[j]; 90 } 91 } 92 for(j=0;j<len&&state[j]<k;j++) 93 for(s=0;s<len&&state[s]<k;s++) 94 { 95 befor[j][s]=now[j][s]; 96 now[j][s]=0; 97 } 98 } 99 hxl=0; 100 for(j=0;j<len&&state[j]<k;j++) 101 for(s=0;s<len&&state[s]<k;s++) 102 if( hxl< befor[j][s] ) 103 hxl=befor[j][s]; 104 printf("%d ",hxl); 105 } 106 int main() 107 { 108 int n,m; 109 int i,j,x; 110 Init(); 111 while(scanf("%d%d",&n,&m)>0) 112 { 113 for(i=1;i<=n;i++) 114 { 115 a[i]=0; 116 for(j=1;j<=m;j++) 117 { 118 scanf("%d",&x); 119 a[i]=a[i]<<1; 120 a[i]+=x; 121 } 122 } 123 solve(n,m); 124 } 125 return 0; 126 }