【洛谷3335】【ZJOI2013】蚂蚁寻路
来源:互联网 发布:java去掉括号内容 编辑:程序博客网 时间:2024/06/08 18:15
题目描述
在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长。蚂蚁转弯是有一定特点的,即它的转弯序列一定是如下的形式:右转,右转,左转,左转,右转,右转…左转,左转,右转,右转,右转。即两次右转和两次左转交替出现的形式,最后两次右转(最后两次一定是右转)后再多加一次右转。我们还知道,蚂蚁不会在同一个位置连续旋转两次,并且蚂蚁行走的路径除了起点以外,不会到达同一个点多次,它最后一定是回到起点然后结束自己的行程,而且蚂蚁只会在棋盘格子的顶点处转弯。
现在已知棋盘大小、每个格子的权值以及左转次数/2 的值,问蚂蚁走出的路径围出的封闭图形,权值之和最大可能是多少。
输入输出格式
输入格式:在输入文件ant.in 中,第一行三个数n,m,k。意义如题目描述。
接下来一个n 行m 列的整数矩阵,表示棋盘。
输出格式:一个数,表示蚂蚁所走路径围出的图形可能的最大权值和。
输入输出样例
2 5 2-1 -1 -1 -1 -1-1 -1 -1 -1 -1
-8
说明
【样例说明】
除了第一行的第二个和第一行的第四个都要围起来才至少合法。
【数据规模与约定】
10%的数据所有格子中权值均非负
另20%的数据n=2
另30%的数据k=0
100%的数据1≤n≤100,1≤m≤100,0≤k≤10 保证存在合法路径,数据有梯度,格子中每个元素的值绝对值不超过 10000
题解
那么自己在草稿纸上画画写写就很容易发现,这题其实是要你在一个n*m大小的矩形中框出一个长城形状的子图,使得子图包含的权值和最大。框出图形的底和左右两边都是直的,上端是一高一低间隔排布,总共有2*k+1个(间隔k次)(如下图)
那么从图中我们可以看出,其实是要求2*k+1个同底的子矩形相连组合起来取得的最大和。
这种题目做的时候很容易往高维度想啊,f[i][j][p][h]表示当前这个子矩形的右下角为(i,j),是第p个矩形,高度为h时取得的最优解。
g[i][j][p][h][0/1]表示当前这个子矩形的右下角为(i,j),是第p个矩形,高度大于等于/小于等于h时的最优解。
得出转移方程:f[i][j][p][h]=max(f[i][j-1][p][h],g[i][j-1][p-1][h][p%2])+s[i][j]-s[h-1][j]
每得出一种转移方式,我们都要想,为什么是这样?
第一个f[i][j-1][p][h]就表示这一列与上一列还在同一个矩形内,变化的只是列+1。
第二个就表示从第j列开始是一个新的矩形。由于矩形是一高一低间隔排布,假设第p个矩形是高的,那么第p-1个矩形肯定要比它低,而高的矩形都是奇数号,所以就是g[i][j][j-1][p-1][h][p%2],低的矩形也同理。
那么g[i][j][p][h][0/1]就在f[i][j][p][h]全更新完后,按照定义的性质从高到低和从低到高分别扫一遍,转移
g[i][j][p][h][0]=max(g[i][j][p][h -1][0],f[i][j][p][h -1])
g[i][j][p][h][1]=max(g[i][j][p][h+1][1],f[i][j][p][h+1])
边界条件为f[i][0][p][h]=g[i][0][p][h][1]=g[i][0][p][h][0]=-inf
最后ans用f[i][j][k][i],g[i][j][k][i][0]来更新。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=210;const int inf=1000000000;int n,m,k;int a[maxn][maxn],s[maxn][maxn],f[maxn][maxn][maxn],g[maxn][maxn][maxn][3],ans=-inf;int main(){scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&a[i][j]);s[i][j]=s[i-1][j]+a[i][j];}k=k*2+1;for(int i=1;i<=k;i++)for(int j=1;j<=n;j++)f[0][i][j]=g[0][i][j][1]=g[0][i][j][0]=-inf;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){for(int p=1;p<=k;p++){for(int h=i;h>=1;h--)f[j][p][h]=max(f[j-1][p][h],g[j-1][p-1][h][p%2])+s[i][j]-s[h-1][j];g[j][p][1][0]=-inf;for(int h=2;h<=i;h++)g[j][p][h][0]=max(g[j][p][h-1][0],f[j][p][h-1]);g[j][p][i][1]=-inf;for(int h=i-1;h>=1;h--)g[j][p][h][1]=max(g[j][p][h+1][1],f[j][p][h+1]);} ans=max(ans,max(f[j][k][i],g[j][k][i][0]));}}printf("%d\n",ans);return 0;}
- 【洛谷3335】【ZJOI2013】蚂蚁寻路
- BZOJ 3111 [Zjoi2013]蚂蚁寻路
- [DP] BZOJ 3111 [Zjoi2013]蚂蚁寻路
- bzoj 3111: [Zjoi2013]蚂蚁寻路
- bzoj 3111: [Zjoi2013]蚂蚁寻路 动态规划
- bzoj 3111: [Zjoi2013]蚂蚁寻路(DP)
- 洛谷 P1367 蚂蚁
- 蚂蚁
- 蚂蚁
- 蚂蚁
- 蚂蚁
- 蚂蚁
- [BZOJ 3111] ZJOI 2013 蚂蚁寻路 · 动态规划
- 整体二分\cdq分治——洛谷P3332 [ZJOI2013]K大数查询
- [BZOJ3112][Zjoi2013]防守战线
- [Zjoi2013]K大数查询
- [BZOJ3110~3115]ZJOI2013
- 【BZOJ3112】[ZJOI2013]防守战线
- 1021. 个位数统计 (15)
- HDU 5510 Bazinga(KMP||strstr神器+些许优化)
- 栈的简单使用和运行结果
- 《Effective Java》(23~25)阅读笔记
- [cnblogs镜像]页面定制CSS代码初探(二):自定义h2标题样式 添加阴影 添加底色 等
- 【洛谷3335】【ZJOI2013】蚂蚁寻路
- [cnblogs镜像]Xcode 下“ did not have any applicable content ”分析及解决
- android-SVG
- [cnblogs镜像]Xcode7 下导入第三方库 图文介绍
- Android学习笔记13---实时搜索框
- Linux操作系统命令学习第四天
- Django入门-6:视图-中间件、CSRF
- Algorithm5——排序算法
- matlab permute函数