题目描述

在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长。

蚂蚁转弯是有一定特点的,即它的转弯序列一定是如下的形式:右转,右转,左转,左转,右转,右转…左转,左转,右转,右转,右转。即两次右转和两次左转交替出现的形式,最后两次右转(最后两次一定是右转)后再多加一次右转。我们还知道,蚂蚁不会在同一个位置连续旋转两次,并且蚂蚁行走的路径除了起点以外,不会到达同一个点多次,它最后一定是回到起点然后结束自己的行程,而且蚂蚁只会在棋盘格子的顶点处转弯。

现在已知棋盘大小、每个格子的权值以及左转次数/2 的值,问蚂蚁走出的路径围出的封闭图形,权值之和最大可能是多少。

输入输出格式

输入格式:

在输入文件ant.in 中,第一行三个数n,m,k。意义如题目描述。

接下来一个n 行m 列的整数矩阵,表示棋盘。

输出格式:

一个数,表示蚂蚁所走路径围出的图形可能的最大权值和。

输入输出样例

输入样例#1:

2 5 2
-1 -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]蚂蚁寻路的更多相关文章

  1. bzoj3111: [Zjoi2013]蚂蚁寻路

    题目链接 bzoj3111: [Zjoi2013]蚂蚁寻路 题解 发现走出来的图是一向上的凸起锯齿状 对于每个突出的矩形dp一下就好了 代码 /* */ #include<cstdio> ...

  2. 3111: [Zjoi2013]蚂蚁寻路 - BZOJ

    题目描述 Description在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长.蚂蚁转弯是有一定 ...

  3. 洛谷P1916 小书童——蚂蚁大战

    题目背景 小A在你的帮助下,开始“刷题”,他在小书童里发现了一款叫“蚂蚁大战”(又称蛋糕保卫战)的游戏.(你懂得) 题目描述 游戏中会出现n只蚂蚁,分别有a1,a2……an的血量,它们要吃你的蛋糕.当 ...

  4. 洛谷 P3332 [ZJOI2013]K大数查询 解题报告

    P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...

  5. 洛谷——P1916 小书童——蚂蚁大战

    P1916 小书童——蚂蚁大战 题目背景 小A在你的帮助下,开始“刷题”,他在小书童里发现了一款叫“蚂蚁大战”(又称蛋糕保卫战)的游戏.(你懂得) 题目描述 游戏中会出现n只蚂蚁,分别有a1,a2…… ...

  6. 【洛谷P1367】蚂蚁

    蚂蚁 [题目描述] 在一根无限长的木棍上,用n只蚂蚁,每只蚂蚁有一个初始位置和初始朝向,蚂蚁们以每秒一个单位的速度向前移动,当两只蚂蚁相遇时,它们会掉头(掉头时间忽略不计).现给出每只蚂蚁的初始位置和 ...

  7. 洛谷 P1916 小书童——蚂蚁大战

    P1916 小书童——蚂蚁大战 题目背景 小A在你的帮助下,开始“刷题”,他在小书童里发现了一款叫“蚂蚁大战”(又称蛋糕保卫战)的游戏.(你懂得) 题目描述 游戏中会出现n只蚂蚁,分别有a1,a2…… ...

  8. BZOJ 3111: [Zjoi2013]蚂蚁寻路

    Sol DP. 首先观察转折,画画图,看看移动路线,可以非常轻易的发现如果走到起点的下方是回不去的.. 然后它就相当于一个底部是平的,顶部凹凹凸凸的形状,每右转两次或左转两次就会形成小矩阵,这样就可以 ...

  9. [洛谷P3332][ZJOI2013]K大数查询

    题目大意:有$n$个位置,$m$个操作.操作有两种: $1\;l\;r\;x:$在区间$[l,r]$每个位置加上一个数$x$ $2\;l\;r\;k:$询问$[l,r]$中第$k$大的数是多少. 题解 ...

随机推荐

  1. 2019牛客暑期多校训练营(第八场)E.Explorer

    链接:https://ac.nowcoder.com/acm/contest/888/E来源:牛客网 Gromah and LZR have entered the fifth level. Unli ...

  2. 洛谷——P1305 新二叉树(新建二叉树以及遍历)

    题目描述输入一串二叉树,用遍历前序打出. 输入输出格式输入格式: 第一行为二叉树的节点数n.(n \leq 26n≤26) 后面n行,每一个字母为节点,后两个字母分别为其左右儿子. 空节点用*表示 输 ...

  3. Visual Studio Team Services使用教程【4】:默认团队checkin权限修改

    2017.4.23之后建议朋友看下面的帖子 TFS2017 & VSTS 实战(繁体中文视频) Visual Studio Team Services(VSTS)与敏捷开发ALM实战关键报告( ...

  4. 在Linux中执行.sh脚本,异常/bin/sh^M

    在Linux中执行.sh脚本,异常/bin/sh^M 在linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory. 分 ...

  5. [reviewcode] 那些基础comments

    多次提醒我,为变量取个合适的名字, so cute person: Not a big deal, but try using variable names better than my_sa 每个参 ...

  6. lombok优缺点

    优点: 能通过注解的形式自动生成构造器.getter/setter.equals.hashcode.toString等方法,提高了一定的开发效率 让代码变得简洁,不用过多的去关注相应的方法 属性做修改 ...

  7. $ CometOJ-Contest\#11\ D$ $Kruscal$重构树

    正解:$Kruscal$重构树 解题报告: 传送门$QwQ$ 发现一个图上搞就很麻烦,考虑变为生成树达到原有效果. 因为在询问的时候是要求走到的点编号尽量小,发现这个时候点的编号就成为限制了,于是不难 ...

  8. fiddler 手机 https 抓包

    fiddler手机抓包原理fiddler手机抓包的原理与抓pc上的web数据一样,都是把fiddler当作代理,网络请求走fiddler,fiddler从中拦截数据,由于fiddler充当中间人的角色 ...

  9. Okhttp解析—Okhttp概览

    Okhttp解析-Okhttp概览 Okhttp作为目前Android使用最为广泛的网络框架之一,我们有必要去深入了解一下,本文是Okhttp解析的第一篇,主要是从宏观上认识Okhttp整个架构是如何 ...

  10. 1094 谷歌的招聘 (20 分)C语言

    2004 年 7 月,谷歌在硅谷的 101 号公路边竖立了一块巨大的广告牌(如下图)用于招聘.内容超级简单,就是一个以 .com 结尾的网址,而前面的网址是一个 10 位素数,这个素数是自然常数 e ...