Description
在一个n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长。蚂蚁转弯是有一定特点的,即它的转弯序列一定是如下的形式:
右转,右转,左转,左转,右转,右转…左转,左转,右转,右转,右转。
即两次右转和两次左转交替出现的形式,最后两次右转(最后两次一定是右转)后再多加一次右转。我们还知道,蚂蚁不会在同一个位置连续旋转两次,并且蚂蚁行走的路径除了起点以外,不会到达同一个点多次,它最后一定是回到起点然后结束自己的行程,而且蚂蚁只会在棋盘格子的顶点处转弯。
设k 为蚂蚁左转的次数除以2,当k=0 时,蚂蚁可能行走的路径如下图:
转弯序列为:右转,右转,左转,左转,右转,右转,右转。
现在已知棋盘大小、每个格子的权值以及左转次数/2 的值,问蚂蚁走出的路径围出的封闭图形,权值之和最大可能是多少。
10%的数据所有格子中权值均非负
另20%的数据n=2
另30%的数据k=0
100%的数据1≤n≤100,1≤m≤100,0≤k≤10 保证存在合法路径,数据有梯度,格子中每个元素的值绝对值不超过10000
Solution
辣鸡csdn,强行绑定手机号还要一波引流
早上写完60p就开始神游了。。其实挺简单
首先可以知道画出来的图形一定是k指山( ̄▽ ̄)",并且下部一定是平的
我们枚举下部就可以dp了。设f[x,y,w]表示到了第x列,这一列高度为y,是第段。可以发现第x列凸出来当且仅当w为奇数,并且转移是一段前缀后缀max,那么直接做就可以了
我的代码跑不了k=0的情况,还要加一个特判。。
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (register int i=st;i<=ed;++i)
#define drp(i,st,ed) for (register int i=st;i>=ed;--i)
#define fill(x,t) memset(x,t,sizeof(x))
const int INF=0x3f3f3f3f;
const int N=205;
int f[N][N][22],g[N][N][22],h[N][N][22];
int r[N][N],s[N][N];
int get(int a,int b,int c,int d) {
static int tmp[5];
if (a<c) std:: swap(a,c);
if (b<d) std:: swap(b,d);
return s[a][b]-s[a][d-1]-s[c-1][b]+s[c-1][d-1];
}
void upd(int &x,int v) {
(x<v)?(x=v):0;
}
int main(void) {
freopen("data.in","r",stdin);
int n,m,k,ans=-INF; scanf("%d%d%d",&n,&m,&k);
rep(i,1,n) rep(j,1,m) {
scanf("%d",&r[i][j]);
s[i][j]=s[i-1][j]+s[i][j-1]+r[i][j]-s[i-1][j-1];
}
if (k==0) {
rep(a,1,n) rep(b,1,m) {
rep(c,a,n) rep(d,b,m) {
upd(ans,get(a,b,c,d));
}
}
return 0&printf("%d\n", ans);
}
k=k*2+1;
rep(i,1,n) {
fill(f,-31); fill(g,-31); fill(h,-31);
rep(x,0,m) {
drp(y,i,1) f[x][y][0]=0;
drp(y,i,1) upd(g[x][y][0],std:: max(g[x][y+1][0],f[x][y][0]));
rep(y,1,i) upd(h[x][y][0],std:: max(h[x][y-1][0],f[x][y][0]));
}
rep(w,1,k) {
rep(x,1,m) {
drp(y,i,1) {
upd(f[x][y][w],f[x-1][y][w]+get(i,x,y,x));
if (w&1) upd(f[x][y][w],g[x-1][y+1][w-1]+get(i,x,y,x));
else upd(f[x][y][w],h[x-1][y-1][w-1]+get(i,x,y,x));
}
drp(y,i,1) upd(g[x][y][w],std:: max(g[x][y+1][w],f[x][y][w]));
rep(y,1,i) upd(h[x][y][w],std:: max(h[x][y-1][w],f[x][y][w]));
}
}
rep(x,1,m) rep(y,1,i) upd(ans,f[x][y][k]);
}
printf("%d\n", ans);
return 0;
}