HDU 4539 郑厂长系列故事——排兵布阵 (状态压缩DP)
来源:互联网 发布:淘客app源码 编辑:程序博客网 时间:2024/05/28 05:14
中文题,题意不再累赘。
思路:对于第 i 行的放士兵,影响它的只有第 i-1 行和 i-2 行,所以暴力枚举符合这三行的状态
state[i],state[j],state[k]. 接下来就是二进制的巧妙应用了。
具体题解看代码注释!!!
#include<cstdio>#include<stdlib.h>#include<string.h>#include<string>#include<map>#include<cmath>#include<iostream>#include <queue>#include <stack>#include<algorithm>#include<set>using namespace std;#define INF 1e8#define inf -0x3f3f3f3f#define eps 1e-8#define LL long long#define N 100001#define mol 100000000int lp(int a,int b){return a&b;}int dp[105][200][200];//dp[i][j][k],表示第 i 行是 state[j]状态i-1行是state[k]状态的最大值int state[200];//符合规定的状态int base[200];//给定矩阵的初始状态int sum[200];//sum[i]:状态satet[i]的士兵数int n,m,g;int main(){while(~scanf("%d%d",&n,&m)){memset(base,0,sizeof(base)); memset(dp,0,sizeof(dp)); memset(state,0,sizeof(state)); memset(sum,0,sizeof(sum)); if(n==0||m==0){printf("0\n");continue;}for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&g);if(g==0)base[i]+=1<<(j);//初始状态二进制表示}}int num=0;for(int i=0;i<(1<<m);i++){if(lp(i,i<<2)||lp(i,i>>2)) continue;//状态i要满足它不能攻击它的前两个和后两个int k=i;while(k)//算出k有多少个1(士兵){sum[num]+=k&1;k=k>>1;}state[num++]=i;}for(int i=0;i<num;i++)//初始第0行的状态{if(lp(state[i],base[0])) continue;dp[0][i][0]=sum[i];}for(int i=0;i<num;i++)//在满足第0行的状态下寻找第1行的状态{if(lp(state[i],base[1])) continue;for(int j=0;j<num;j++){if(lp(state[j],base[0])) continue;if(lp(state[j]<<1,state[i])||lp(state[j]>>1,state[i])) continue;dp[1][i][j]=max(dp[1][i][j],dp[0][j][0]+sum[i]);}}for(int i=0;i<num;i++)//在满足第0,1行的状态下寻找第2行的状态{if(lp(state[i],base[2])) continue;for(int j=0;j<num;j++){if(lp(state[j],base[1])) continue;for(int k=0;k<num;k++){if(lp(state[k],base[0])) continue;if(lp(state[i]<<1,state[j])||lp(state[i]>>1,state[j])) continue;if(lp(state[j]<<1,state[k])||lp(state[j]>>1,state[k])) continue;if(lp(state[i],state[k])) continue;dp[2][i][j]=max(dp[2][i][j],dp[1][j][k]+sum[i]);}}}for(int r=3;r<n;r++)//从第3行开始{for(int i=0;i<num;i++)//暴力枚举三行的状态state[i],state[j],state[k]{if(lp(base[r],state[i])) continue;for(int j=0;j<num;j++){if(lp(base[r-1],state[j])) continue;if(lp(state[i]<<1,state[j])||lp(state[i]>>1,state[j])) continue;for(int k=0;k<num;k++){if(lp(base[r-2],state[k])) continue;if(lp(state[j]<<1,state[k])||lp(state[j]>>1,state[k])) continue;if(lp(state[i],state[k])) continue;dp[r][i][j]=max(dp[r-1][j][k]+sum[i],dp[r][i][j]);}}}}int ans=0;for(int i=0;i<num;i++){for(int j=0;j<num;j++)ans=max(ans,dp[n-1][i][j]);}printf("%d\n",ans);}return 0;}/*6 61 0 0 0 0 10 0 0 0 0 00 0 1 1 0 00 0 1 1 0 00 0 1 1 0 01 0 1 1 0 13 31 1 11 1 11 1 16 60 0 0 0 0 00 0 0 0 0 00 0 1 1 0 00 0 0 0 0 00 0 0 0 0 00 0 0 0 0 06 61 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 11 1 1 1 1 10 61 61 1 1 1 1 12 61 1 1 1 1 11 1 1 1 1 1Answer:63212044*/
0 0
- 状态压缩dp hdu 4539 郑厂长系列故事——排兵布阵
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩DP)
- hdu 4539 郑厂长系列故事——排兵布阵 (状态压缩dp)
- hdu 4539 郑厂长系列故事——排兵布阵 状态压缩dp
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- hdu 4539 郑厂长系列故事——排兵布阵 状态压缩+dp;
- hdu 4539 郑厂长系列故事——排兵布阵 (状态压缩dp)
- HDU 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- HDU 4539 郑厂长系列故事——排兵布阵 (状态压缩DP)
- HDU ACM 4539 郑厂长系列故事——排兵布阵->状态压缩DP
- 【状态压缩DP】 HDU 4539 郑厂长系列故事——排兵布阵
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- (待解决) hdu HDU4539 郑厂长系列故事——排兵布阵 (状态压缩dp~)
- HDOJ 4539 郑厂长系列故事——排兵布阵(状态压缩dp)
- 状态压缩(1) Hdu 4539 郑厂长系列故事——排兵布阵
- Hdu 4539 郑厂长系列故事——排兵布阵 状态压缩
- HDU-4539郑厂长系列故事——排兵布阵(状态压缩,动态规划)
- hdu 4539 郑厂长系列故事——排兵布阵(状态压缩)
- Unix时间戳字符串转int (unixtime)
- poj 3450 Corporate Identity(数据结构:KMP)
- uva 10780 Again Prime? No Time. 质因子乱搞
- 【android基础】数据存储
- 机房收费系统---组合查询
- HDU 4539 郑厂长系列故事——排兵布阵 (状态压缩DP)
- ImageSwitcher,里面的图片放大缩小,有效果
- LeetCode String to Integer (atoi)
- 数字证书原理
- 职场需求---Android开发
- Action中的list值传值到js获取并填充下拉框
- 泛型初步理解
- Cocos2dx内存管理
- MATLAB数据拟合(二)