bzoj 1187: [HNOI2007]神奇游乐园 插头dp
2016-04-14 07:59
465 查看
一道最裸的插头dp,然而还是调了很久。。代码2.6k+调试语句1.5k。。不过这次代码很多可以不需要的但是这种题目关键还是要思路清晰。。。
然而窝用了3进制作死时间被爆出翔。。。。
令dp[i][j][k]表示在第i行第j列状态为k时的最大收入,其中k表示插头的状态,即一个括号序列。令上面一段连续的在轮廓线上的左端点为'(',右端点为')',或者也可以看成是从左端点出发在轮廓线上面走过某一段连续的路径之后再右端点回到了轮廓线。那么令'('=1,')'=2,没有插头为0,就可以用一个三进制来压缩状态了。
那么可以用除法和取模快速得到某一位,在轮廓线的转折处有3*3=9中情况分类讨论。
1.左边和上面都没有插头,那么这一格可以选择不放,或者向下放一个'(',同时向右放一个')';
2.左边或者上面有一个'('插头,那么这一格只能向下放一个'('或者向右放一个'(';
3.左边或者上面有一个')'插头,同上;
4.左边和上面都有'('插头,这种情况比较复杂,显然是需要把两个插头连起来的,但是状态会有变化,如图(有点丑QAQ):
![](http://img.blog.csdn.net/20160414075551524?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
可以发现此时上面的'('插头对应的')'插头变成了'('插头。。。于是为了O(1)转移我们需要预处理每一个状态的每一位和它对应的括号的位置。然后修改一下那个位置的状态即可。
5.上面和左边都是')'插头,同上;
6.左边是'('插头,上面是')'插头,此时应该判断其它地方有没有插头,如果没有插头就更新答案。不进行转移;
7.左边是')'插头,上面是'('插头,那么直接连上即可。
然后就是考验细心程度的时候了。。。
AC代码如下:
by lych
2016.4.14
然而窝用了3进制作死时间被爆出翔。。。。
令dp[i][j][k]表示在第i行第j列状态为k时的最大收入,其中k表示插头的状态,即一个括号序列。令上面一段连续的在轮廓线上的左端点为'(',右端点为')',或者也可以看成是从左端点出发在轮廓线上面走过某一段连续的路径之后再右端点回到了轮廓线。那么令'('=1,')'=2,没有插头为0,就可以用一个三进制来压缩状态了。
那么可以用除法和取模快速得到某一位,在轮廓线的转折处有3*3=9中情况分类讨论。
1.左边和上面都没有插头,那么这一格可以选择不放,或者向下放一个'(',同时向右放一个')';
2.左边或者上面有一个'('插头,那么这一格只能向下放一个'('或者向右放一个'(';
3.左边或者上面有一个')'插头,同上;
4.左边和上面都有'('插头,这种情况比较复杂,显然是需要把两个插头连起来的,但是状态会有变化,如图(有点丑QAQ):
可以发现此时上面的'('插头对应的')'插头变成了'('插头。。。于是为了O(1)转移我们需要预处理每一个状态的每一位和它对应的括号的位置。然后修改一下那个位置的状态即可。
5.上面和左边都是')'插头,同上;
6.左边是'('插头,上面是')'插头,此时应该判断其它地方有没有插头,如果没有插头就更新答案。不进行转移;
7.左边是')'插头,上面是'('插头,那么直接连上即可。
然后就是考验细心程度的时候了。。。
AC代码如下:
#include<iostream> #include<cstdio> #include<cstring> #define inf 1000000000 using namespace std; int m,n,a[105][7],lp[2187][7],rp[2187][7],f[105][7][2187],c[15]; bool bo[2187]; bool check(int t){ int i,x,s=0; for (i=0; i<=n; i++){ x=t/c[i]%3; if (x==1) s++; else if (x==2) s--; if (s<0) return 0; } return !s; } int calc(int t){ int i,x,ans=0,s=0; for (i=0; i<n; i++){ x=t/c[i]%3; if (x==1){ s++; ans+=a[1][i+1]; } else if (x==2){ s--; ans+=a[1][i+1]; } else if (s) ans+=a[1][i+1]; if (s>1) return -inf; } return ans; } int findl(int t,int p){ int i,x,s=1; for (i=p-1; i>=0; i--){ x=t/c[i]%3; if (x==1) s--; else if (x==2) s++; if (!s) return i; } return 0; } int findr(int t,int p){ int i,x,s=1; for (i=p+1; i<=n; i++){ x=t/c[i]%3; if (x==1) s++; else if (x==2) s--; if (!s) return i; } return n; } void up(int &x,int y){ if (x<y) x=y; } int main(){ scanf("%d%d",&m,&n); int i,j,k,x,u,v,tmp; for (i=1; i<=m; i++) for (j=1; j<=n; j++) scanf("%d",&a[i][j]); c[0]=1; for (i=1; i<=n+1; i++) c[i]=3*c[i-1]; memset(f,192,sizeof(f)); for (i=0; i<c[n+1]; i++) if (check(i)){ bo[i]=1; for (j=0; j<=n; j++){ k=i/c[j]%3; if (k==2) lp[i][j]=findl(i,j); else if (k==1) rp[i][j]=findr(i,j); } if (!(i/c )) f[1] [i]=calc(i); } int ans=-inf; for (i=2; i<=m; i++){ for (j=0; j<c[n+1]; j++) if (bo[j] && !(j/c )){ u=j%3; x=(j-u)*3; tmp=f[i-1] [j]; if (!u){ up(f[i][1][x+7],tmp+a[i][1]); up(f[i][1][x],tmp); } else if (u==1){ up(f[i][1][x+1],tmp+a[i][1]); up(f[i][1][x+3],tmp+a[i][1]); } } for (j=2; j<=n; j++) for (k=0; k<c[n+1]; k++) if (bo[k]){ u=k/c[j-1]%3; v=k/c[j]%3; x=k-u*c[j-1]-v*c[j]; tmp=f[i][j-1][k]; if (!u && !v){ up(f[i][j][x],tmp); up(f[i][j][x+c[j-1]+2*c[j]],tmp+a[i][j]); } else if (!u && v==1 || u==1 && !v){ up(f[i][j][x+c[j-1]],tmp+a[i][j]); up(f[i][j][x+c[j]],tmp+a[i][j]); } else if (!u && v==2 || u==2 && !v){ up(f[i][j][x+2*c[j-1]],tmp+a[i][j]); up(f[i][j][x+2*c[j]],tmp+a[i][j]); } else if (u==1 && v==1){ up(f[i][j][x-c[rp[k][j]]],tmp+a[i][j]); } else if (u==2 && v==2){ up(f[i][j][x+c[lp[k][j-1]]],tmp+a[i][j]); } else if (u==1 && v==2){ if (!x) up(ans,tmp+a[i][j]); } else{ up(f[i][j][x],tmp+a[i][j]); } } } printf("%d\n",ans); return 0; }
by lych
2016.4.14
相关文章推荐
- 3770: 疯狂的限制 乱搞
- Android 基本控件的使用一(用户的登录界面)
- 173. Binary Search Tree Iterator
- 2016年4月14日
- Penguins DbTools数据库管理移植差分工具(EXCEL相关) ver 20160414
- HTML5_Web Workers
- JS创建新元素组与删除当前元素组
- Maven教程
- 欢迎使用CSDN-markdown编辑器
- LeetCode 281. Zigzag Iterator(之字形迭代器)
- CQOI2016 bzoj4522 密钥破解
- Cocos2D在新版Swift中常量枚举值引用代码的修改
- Cocos2D在新版Swift中常量枚举值引用代码的修改
- Cocos2D在新版Swift中常量枚举值引用代码的修改
- delegate的内存管理属性是weak还是assign
- Spark on YARN 部署
- 每日开源新闻速递(2016/4/14):Ubuntu 16.04 将同时提供 snap 软件包格式
- js渲染引擎 tempo.js
- LeetCode 280. Wiggle Sort(摇摆排序)
- C++游戏系列:目录