您的位置:首页 > 其它

VIJOS 1143 三方格取数

2013-11-06 17:15 197 查看


背景

JerryZhou同学经常改编习题给自己做。
这天,他又改编了一题。。。。。


描述

设有N*N的方格图,我们将其中的某些方格填入正整数,

而其他的方格中放入0。
某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角。
在走过的路上,他取走了方格中的数。(取走后方格中数字变为0)

此人从左上角到右下角共走3次,试找出3条路径,使得取得的数总和最大。


格式

输入格式

第一行:N (4<=N<=20)

接下来一个N*N的矩阵,矩阵中每个元素不超过80,不小于0

输出格式

一行,表示最大的总和。


样例1

样例输入

4
1 2 3 4
2 1 3 4
1 2 3 4
1 3 2 4


样例输出

39



限制

各个测试点1s


提示

多进程DP

就像传纸条。。。恩

第一次居然ce了 忘了memset的cstring了!!!!!

F[X][Y][J][K]表示第一次取到x和y

第二次取到j x+y-j

第三次取到k x+y-k时取到的最大值

然后要判断 可能走一个格子 这时候另一次要+0

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int s[22][22];
int f[22][22][22][22];
int m,a,b,c;

int move(int bu,int x1,int x2,int x3)
{
int y1=bu-x1,y2=bu-x2,y3=bu-x3;
if(x1==x2&&x2==x3)return s[x1][y1];
if(x1==x2&&x2!=x3)return s[x1][y1]+s[x3][y3];
if(x1!=x2&&x2==x3)return s[x1][y1]+s[x3][y3];
if(x1==x3&&x2!=x3)return s[x1][y1]+s[x2][y2];
if(x1!=x2&&x2!=x3&&x3!=x1)return s[x1][y1]+s[x2][y2]+s[x3][y3];
return 0;
}
int work(int x,int y,int j,int k)
{
int bu=x+y;
if(x>m||y>m||j>m||k>m||bu-j>m||bu-k>m)return 0;
if(x<=0||y<=0||j<=0||k<=0||bu-j<=0||bu-k<=0)return 0;
if(f[x][y][j][k]!=-1)return f[x][y][j][k];

f[x][y][j][k]=max(f[x][y][j][k],work(x-1,y,j,k)+move(x+y,x,j,k));
f[x][y][j][k]=max(f[x][y][j][k],work(x-1,y,j-1,k)+move(x+y,x,j,k));
f[x][y][j][k]=max(f[x][y][j][k],work(x-1,y,j,k-1)+move(x+y,x,j,k));
f[x][y][j][k]=max(f[x][y][j][k],work(x-1,y,j-1,k-1)+move(x+y,x,j,k));
f[x][y][j][k]=max(f[x][y][j][k],work(x,y-1,j,k)+move(x+y,x,j,k));
f[x][y][j][k]=max(f[x][y][j][k],work(x,y-1,j-1,k)+move(x+y,x,j,k));
f[x][y][j][k]=max(f[x][y][j][k],work(x,y-1,j,k-1)+move(x+y,x,j,k));
f[x][y][j][k]=max(f[x][y][j][k],work(x,y-1,j-1,k-1)+move(x+y,x,j,k));

return f[x][y][j][k];
}
int main()
{
scanf("%d",&m);
memset(f,-1,sizeof(f));
for(a=1;a<=m;a++)
for(b=1;b<=m;b++)
scanf("%d",&s[a][b]);

cout<<work(m,m,m,m)<<'\n';
return 0;
}


话说不会递推的DP了。。。
现在只会递归。。。

求不爆栈

NOIP RP++
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: