洛谷P3335 [ZJOI2013]蚂蚁寻路
题目描述
在一个 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
题解:
首先需要看明白题,什么左转右转的
自己举几个例子就可以知道,围成的图形大概长这样:
凹进去几个,就是k(比如上图k=3)
然后,其实挺明显能看出来是dp
但怎么dp是个问题!想了好久好久
一开始我是将围成的图形拆成k*2+1个矩形来想,但后来发现可以一列一列考虑
dp[i][j][h][l]表示当前起点在第i行,考虑到第j列,当前高度为h(指的是顶上那个点的行数),还可或起或伏l次(包括本次的)
dp[i][j][h][l]=max(dp[i][j+1][h][l],dp[i][j+1][h'][l-1])
前者是第j+1列与当前列高度相同(说白了在一个矩形中),后者h'就是第j+1列应比这列的高还是矮(取决于l的奇偶)
发现h'如果一个一个枚举好慢啊,那就开两个数组记录一下好了
写题时细节很多,感觉整个人都不好了……不可思议的是居然过了,还是很开心的
注意:提交的第一次只有60分,剩下的MLE了……所以说下次要注意数组大小!!!
代码:
#include<cstdio>
#include<iostream>
#define INF 100000000
using namespace std; const int MAXN = ;
int dp[MAXN][MAXN][MAXN][];
int big[MAXN][MAXN][],sml[MAXN][MAXN][];
int a[MAXN][MAXN],sum[MAXN][MAXN];
int n,m,k; int num(int y,int x0,int x){
return sum[x][y]-sum[x][y-]-sum[x0-][y]+sum[x0-][y-];
} int main()
{
int i,j,w,h,l,s;
scanf("%d%d%d",&n,&m,&k);
w=*k+;
for(i=;i<=n;i++) sum[i][]=;
for(i=;i<=m;i++) sum[][i]=;
for(i=;i<=n;i++)
for(j=;j<=m;j++){
scanf("%d",&a[i][j]);
sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-]+a[i][j];
} for(i=;i<=n;i++)
for(j=;j<=m;j++)
for(h=;h<=n+;h++)
for(l=;l<=w;l++)
dp[i][j][h][l]=-INF; for(i=;i<=n;i++){
for(j=;j<=m;j++)
for(h=;h<=n+;h++)
for(l=;l<=w;l++) big[j][h][l]=sml[j][h][l]=-INF;
for(j=m;j>=;j--){
for(l=;l<=(m-j+) && l<=w;l++){
for(h=;h<=i;h++){
s=num(j,h,i);
if(l==) {
if(j==m) dp[i][j][h][l]=s;
else dp[i][j][h][l]=s+max(,dp[i][j+][h][l]);
}
else{
if(l%==)
dp[i][j][h][l]=max(dp[i][j+][h][l],big[j+][h+][l-])+s;
else
dp[i][j][h][l]=max(dp[i][j+][h][l],sml[j+][h-][l-])+s;
}
}
sml[j][][l]=dp[i][j][][l];
for(h=;h<=i;h++) sml[j][h][l]=max(sml[j][h-][l],dp[i][j][h][l]);
big[j][i][l]=dp[i][j][i][l];
for(h=i-;h>=;h--) big[j][h][l]=max(big[j][h+][l],dp[i][j][h][l]);
}
}
} int ans=-INF;
for(i=;i<=n;i++)
for(j=;j+w-<=m;j++)
for(h=;h<=i;h++) ans=max(ans,dp[i][j][h][w]);
printf("%d\n",ans); return ;
}
洛谷P3335 [ZJOI2013]蚂蚁寻路的更多相关文章
- bzoj3111: [Zjoi2013]蚂蚁寻路
题目链接 bzoj3111: [Zjoi2013]蚂蚁寻路 题解 发现走出来的图是一向上的凸起锯齿状 对于每个突出的矩形dp一下就好了 代码 /* */ #include<cstdio> ...
- 3111: [Zjoi2013]蚂蚁寻路 - BZOJ
题目描述 Description在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长.蚂蚁转弯是有一定 ...
- 洛谷P1916 小书童——蚂蚁大战
题目背景 小A在你的帮助下,开始“刷题”,他在小书童里发现了一款叫“蚂蚁大战”(又称蛋糕保卫战)的游戏.(你懂得) 题目描述 游戏中会出现n只蚂蚁,分别有a1,a2……an的血量,它们要吃你的蛋糕.当 ...
- 洛谷 P3332 [ZJOI2013]K大数查询 解题报告
P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...
- 洛谷——P1916 小书童——蚂蚁大战
P1916 小书童——蚂蚁大战 题目背景 小A在你的帮助下,开始“刷题”,他在小书童里发现了一款叫“蚂蚁大战”(又称蛋糕保卫战)的游戏.(你懂得) 题目描述 游戏中会出现n只蚂蚁,分别有a1,a2…… ...
- 【洛谷P1367】蚂蚁
蚂蚁 [题目描述] 在一根无限长的木棍上,用n只蚂蚁,每只蚂蚁有一个初始位置和初始朝向,蚂蚁们以每秒一个单位的速度向前移动,当两只蚂蚁相遇时,它们会掉头(掉头时间忽略不计).现给出每只蚂蚁的初始位置和 ...
- 洛谷 P1916 小书童——蚂蚁大战
P1916 小书童——蚂蚁大战 题目背景 小A在你的帮助下,开始“刷题”,他在小书童里发现了一款叫“蚂蚁大战”(又称蛋糕保卫战)的游戏.(你懂得) 题目描述 游戏中会出现n只蚂蚁,分别有a1,a2…… ...
- BZOJ 3111: [Zjoi2013]蚂蚁寻路
Sol DP. 首先观察转折,画画图,看看移动路线,可以非常轻易的发现如果走到起点的下方是回不去的.. 然后它就相当于一个底部是平的,顶部凹凹凸凸的形状,每右转两次或左转两次就会形成小矩阵,这样就可以 ...
- [洛谷P3332][ZJOI2013]K大数查询
题目大意:有$n$个位置,$m$个操作.操作有两种: $1\;l\;r\;x:$在区间$[l,r]$每个位置加上一个数$x$ $2\;l\;r\;k:$询问$[l,r]$中第$k$大的数是多少. 题解 ...
随机推荐
- 递归&时间模块&os模块
递归 递归调用 一个函数,调用了自身,称为递归调用 递归函数:一个会调用自身的函数称为递归函数 凡是循环能干的事,递归都能干 方式: 写出临界条件 找这一次和上一次的关系 假设当前函数已经能用,调用自 ...
- 【Linux】ssh-copy-id三步实现ssh免密登陆
一.本地机器上使用ssh-keygen产生公钥私钥对 ssh-keygen -t rsa -C "XXXX@163.com" --->执行完会在~/.ssh/下生成公钥私钥对 ...
- Github Pages 无法调用 node_modules 文件夹的解决方案
今天写一个demo,用npm安装的前端库,然后想在github的pages上展示出来 发布到github后,发现node_modules文件夹下的js无法调用 google解决方案:新增一个名字为.n ...
- Team Foundation Server 2015使用教程【6】:新增权限为读取器的团队
- Java面向对象程序设计第8章3-5
Java面向对象程序设计第8章3-5 3.String类型有什么特点? 一旦赋值,便不能更改其指向的字符对象 如果更改,则会指向一个新的字符对象 不能为null 4.String什么时候进行值比较,什 ...
- git之分支
分支相互之间互不干扰 1.小乌龟创建分支,切换/检出 创建后直接切换到该分支,另一个需要再切换一下. 2.点击这个可以看到所有的分支,进行删除操作. 3.在fen1,fen2分别进行操作更新,互不 ...
- 程序员必须掌握的性能调优 X Y Z
热评博文:<如何设计出优美的Web API?>,现阅读量超 2500,小伙伴们不要错过哦! 2003 ~ 2008 年,这五年老兵哥我在通信行业做实习生和开发岗,主要用 C / C++ / ...
- python实现上传文件到linux指定目录
今天接到一个小需求,就是想在windows环境下,上传压缩文件到linux指定的目录位置并且解压出来,然后我想了一下,这个可以用python试试写下. 环境:1.linux操作系统一台2.window ...
- JVM探秘:GC日志收集与分析
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 收集GC日志 不同的垃圾收集器,输出的日志格式各不相同,但也有一些相同的特征.熟悉各个 ...
- Jmeter-Ant 生成测试报告配置步骤
1.配置java环境变量(不会的可以自行百度) 2.安装jmeter 3.安装ant,配置ant环境变量 4.将JMeter所在目录下extras子目录里的ant-JMeter-1.1.1.jar复制 ...