[2013腾讯马拉松复赛第二场] HDU 4539 郑厂长系列故事——排兵布阵
2013-03-30 22:10
447 查看
以后做比赛前一定补好睡眠,没有精神A不动题目……,最后一题的题意到2H才发现看错了,原来是要求曼哈顿距离等于2的而不是小于等于2的……,调了半天样例都输出1……。最后只AC了2题,第一个和最后一个,第二个怎么想怎么是爆搜,是不是爆搜?
最后一题排兵布阵是比较经典的状压DP,看群里还有用点独立集做的,还有用插头DP做的?ORZ。
做法跟POJ 1185炮兵阵地,这道经典状压DP神似,连题目都神似。所以具体转移方程也基本一样,需要枚举前两行的状态。具体细节不明白的可以先去搜poj 1185的解题报告。
题目虽然给的时间很多,但是比赛怕超时就先预处理了所有当前行可行的状态。判断当前行k,和k-2行是否兼容跟炮兵阵地的处理方式一样,直接相与。处理k跟k-1行略有不同,是把k-1行的状态搓一个位(其实就是乘2,除2)相与,看这两个结果有没有不等于0的。其他都跟炮兵一样。
View Code
最后一题排兵布阵是比较经典的状压DP,看群里还有用点独立集做的,还有用插头DP做的?ORZ。
做法跟POJ 1185炮兵阵地,这道经典状压DP神似,连题目都神似。所以具体转移方程也基本一样,需要枚举前两行的状态。具体细节不明白的可以先去搜poj 1185的解题报告。
题目虽然给的时间很多,但是比赛怕超时就先预处理了所有当前行可行的状态。判断当前行k,和k-2行是否兼容跟炮兵阵地的处理方式一样,直接相与。处理k跟k-1行略有不同,是把k-1行的状态搓一个位(其实就是乘2,除2)相与,看这两个结果有没有不等于0的。其他都跟炮兵一样。
View Code
#include <set> #include <list> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <vector> #include <bitset> #include <cstdio> #include <string> #include <numeric> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <functional> using namespace std; typedef long long ll; #define Exp 1e-8 #define inf 0x7fffffff #define read freopen("in.txt","r",stdin) #define write freopen("out.txt","w",stdout) #define maxn 200 int n,m,top; int map[105][12],con[maxn][maxn],con2[maxn][maxn]; int state[maxn][2],vm[105],dp[105][maxn][maxn]; int max(int a,int b) { if(a>b)return a; return b; } void prt(int i) { int t=i;while(t)printf("%d",t%2),t>>=1;puts(""); } bool check(int a,int b)//判断当前行的状态能否放入地图中 { if(((~b)&a))return false; return true; } void init()//预处理一行能够放士兵的状态 { int i,j; memset(state,0,sizeof(state)); top=0; for(i=0;i<(1<<10)-1;++i) { if((i&(i<<2)))continue; state[top][0]=i;//0存放状态,1统计个数 for(j=i;j;j-=j&(-j))state[top][1]++; ++top;//prt(state[top-1][0]); } for(i=0;i<top;++i)for(j=0;j<top;++j)//con[i][j]表示当前行跟上一行状态为i,j是否能共存 con[i][j]=!(state[i][0]&state[j][0]); for(i=0;i<top;++i)for(j=0;j<top;++j)//con[i][j]表示当前行跟上二行状态为i,j是否能共存 { int t1=state[i][0]&(state[j][0]<<1); int t2=state[i][0]&(state[j][0]>>1); con2[i][j]=!(t1|t2); } } int main() { //read; init(); int i,j,k,s; while(~scanf("%d%d",&n,&m)) { memset(vm,0,sizeof(vm)); memset(map,0,sizeof(map)); memset(dp,0,sizeof(dp)); for(i=0;i<n;++i) { for(j=0;j<m;++j) { scanf("%d",&map[i][j]); vm[i]=(vm[i]+map[i][j])<<1; } vm[i]>>=1;//地图信息状态压缩 } for(i=0;i<top;++i) { if(check(state[i][0],vm[0])==0)continue; for(j=0;j<top;j++)dp[0][i][j]=state[i][1]; } for(i=0;i<top;++i) { if(check(state[i][0],vm[1])==0)continue; for(j=0;j<top;j++) { if(check(state[j][0],vm[0])==0)continue; if(con2[i][j]==0)continue; dp[1][i][j]=max(dp[1][i][j],dp[0][j][0]+state[i][1]); } } for(s=2;s<n;++s) for(i=0;i<top;++i) { if(check(state[i][0],vm[s])==0)continue; for(j=0;j<top;++j) { if(check(state[j][0],vm[s-1])==0)continue; if(con2[i][j]==0)continue; for(k=0;k<top;++k) { if(check(state[k][0],vm[s-2])==0)continue; if(con2[j][k]==0||con[i][k]==0)continue; dp[s][i][j]=max(dp[s][i][j],state[i][1]+dp[s-1][j][k]); } } } int ans=0; for(i=0;i<top;++i)for(j=0;j<top;++j)ans=max(ans,dp[n-1][i][j]) ; printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 4539 2013腾讯编程马拉松复赛第二场 郑厂长系列故事——排兵布阵
- HDU - 4544 湫湫系列故事――消灭兔子 2013腾讯编程马拉松复赛第三场
- [2013腾讯马拉松复赛第一场]HDU 4532 湫秋系列故事——安排座位
- 2013腾讯编程马拉松初赛第二场(3月22日) 小Q系列故事——为什么时光不能倒流
- 2013腾讯编程马拉松初赛第〇场(HDU 4504)威威猫系列故事——篮球梦
- [2013腾讯马拉松 3月23日]HDU 4517 小小明系列故事——游戏的烦恼
- 2013腾讯编程马拉松初赛第〇场(HDU 4503) 湫湫系列故事——植树节
- 2013腾讯编程马拉松初赛第〇场(HDU 4504)威威猫系列故事——篮球梦
- hdu 4539 郑厂长系列故事——排兵布阵 状态压缩dp
- HDU 4530 小Q系列故事——大笨钟 2013腾讯编程马拉松复赛第一场第一题
- 2013腾讯编程马拉松初赛第〇场(HDU 4503) 湫湫系列故事——植树节
- hdu 4539 郑厂长系列故事——排兵布阵
- 2013腾讯编程马拉松||HDU 4505 小Q系列故事——电梯里的爱情 水水水
- 湫湫系列故事——设计风景线(并查集) [2013腾讯编程马拉松初赛第二场(3月22日)]
- 2013腾讯编程马拉松||HDU 4505 小Q系列故事——电梯里的爱情 水水水
- HDU 4539 郑厂长系列故事——排兵布阵 状压dp
- 2013腾讯编程马拉松初赛第二场(3月22日) 小Q系列故事——为什么时光不能倒流 ---好水!!
- HDU-4539 郑厂长系列故事——排兵布阵 状态压缩DP Or 最大团
- hdu 4539 郑厂长系列故事——排兵布阵
- hdu 4539 郑厂长系列故事——排兵布阵 状态压缩+dp;