HDU 4539 郑厂长系列故事――排兵布阵(状态压缩)
2014-11-06 20:25
225 查看
郑厂长系列故事——排兵布阵
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1954 Accepted Submission(s): 701
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.曼哈顿距离:两点(x1,y1)(x2,y2)的曼哈顿距离为|x1-x2|+|y1-y2|;
2.假如一个点要安排士兵,我们要考虑的是曼哈顿距离为二的几个点是否会造成冲突,即若(x,y)安排人,则(x-2,y)(x-1,y+1),(x,y+2),(x+1,y+1),(x+2,y),(x+1,y-1),(x,y-2),(x-1,y-1)不能有人。然后就是状态方程了:dp[i][j][k] = Max(d[i][j][k],dp[i
- 1][k][l] + sum[j]);
My Code:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define N 110 #define M 200 using namespace std; int n,m,a ; int dp [M][M],cnt,num[M],sum[M]; ///dp[i][j][k] 表示第i行的j状态 i-1行的k状态 的最优解 bool ok(int x) { return (x&(x<<2))||(x&(x<<2));///第x-2个和x+2个位是否有人, // 有的话就不符合条件 } int getsum(int x) { ///1的个数,即放多少个兵 int sum=0; while(x) { if(x&1)sum++; x>>=1; } return sum; } void init() { cnt=0; for(int i=0; i<(1<<m); i++) { ///预处理,压缩 if(!ok(i)) { num[cnt]=i; sum[cnt++]=getsum(i); } } } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { memset(a,0,sizeof a); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { int x; scanf("%d",&x); if(x)continue;///方便计算,把0存为1 a[i]|=(1<<j); } } init(); memset(dp,0,sizeof dp); for(int i=0; i<cnt; i++) { ///处理第一行 if(a[0]&num[i])continue; dp[0][i][0]=sum[i]; } ///递推,要考虑三行的情况, for(int i=1; i<n; i++) { //第一行 for(int j=0; j<cnt; j++) { if(a[i]&num[j])continue; ///第一行与原来矩阵有冲突 for(int k=0; k<cnt; k++) { ///第二行 if(a[i-1]&num[k])continue; if(((num[k]<<1)&num[j])||((num[k]>>1)&num[j]))continue; //i-1行 int Max=-1; for(int l=0; l<cnt; l++) { ///第三行 if(num[j]&num[l])continue; if(((num[l]<<1)&num[k])||((num[l]>>1)&num[k]))continue; Max=max(Max,dp[i-1][k][l]); } dp[i][j][k]=Max+sum[j]; } } } int Max=-1; for(int i=0; i<cnt; i++) for(int j=0; j<cnt; j++) Max=max(Max,dp[n-1][i][j]); printf("%d\n",Max); } return 0; }
相关文章推荐
- hdu-4539 郑厂长系列故事――排兵布阵(状态压缩)
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩)
- 【状态压缩DP】 HDU 4539 郑厂长系列故事——排兵布阵
- HDU 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩DP)
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- HDU-4539 郑厂长系列故事——排兵布阵 状态压缩DP Or 最大团
- HDU-4539郑厂长系列故事——排兵布阵(状态压缩,动态规划)
- 状态压缩(1) Hdu 4539 郑厂长系列故事——排兵布阵
- hdu 4539 郑厂长系列故事——排兵布阵 状态压缩dp
- hdu-4539-郑厂长系列故事――排兵布阵 状态压缩dp
- HDU-4539郑厂长系列故事——排兵布阵(状态压缩,动态规划)
- HDU 4539 郑厂长系列故事――排兵布阵_状态压缩
- HDU 4539 郑厂长系列故事——排兵布阵 (状态压缩DP)
- hdu 4539 郑厂长系列故事——排兵布阵 状态压缩+dp;
- hdu 4539 郑厂长系列故事——排兵布阵 (状态压缩dp)
- HDOJ 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- 状态压缩dp hdu 4539 郑厂长系列故事——排兵布阵
- HDU 4529 郑厂长系列故事——N骑士问题(dp,状态压缩)