【NOIP2000】方格取数

来源:互联网 发布:淘宝贷款上征信吗 编辑:程序博客网 时间:2024/04/30 13:40

【NOIP2000】方格取数

时间限制: 1 Sec  内存限制: 64 MB

题目描述

设有N*N的方格图,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0。如下图所示(见样例):  某人从图的左上角的A 点出发,可以向下行走,也可以向右走,直到到达右下角的B点。

在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。

此人从A点到B 点共走两次,试找出2条这样的路径,使得取得的数之和为最大。

输入

第1行:1个整数N(N<=10),表示N*N的方格图,

第2..?行:每行有3个整数,前2个表示某个方格的位置,第3个数为该位置上所放的数。

一行单独的0表示输入结束。

输出

第1行:1个整数,表示2条路径上取得的最大的和。

样例输入

82  3  132  6   63  5   74  4  145  2  21 5  6   46  3  157  2  140  0  0

样例输出

67


其实走两次可以视为两个人一起走
本来要用4个维度来记录2个人的位置,O(N^4)的时间复杂度,
经过优化,因为两人走的步数是可以随时相同的,用一个step来记录2人走的位置,
记录x1,x2,y=step-x+1,
优化为O(2*n^2)
注意有两者重合的情况,和两者从一个格子里取数转移状态的情况,以及边界
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<stack>#include<queue>#include<vector>#define INF 0x3f3f3f3ftypedef long long int LL;typedef unsigned long long int ULL;LL getint(){    LL ans=0,f=1;char c;    while((c=getchar())<'0'||c>'9')if(c=='-')f=-f;    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}    return ans*f;}using namespace std;LL f[30][15][15],g[15][15];LL max(int a,int b){return a>b?a:b;}LL max(int a,int b,int c,int d){    return max(a,max(b,max(c,d)));}int main(){    int n=getint(),step,x1,x2,a,b,c,l,r;    while(1){        a=getint();b=getint();c=getint();        if(a==0)break;        g[a][b]=c;    }    //y=step-x+1;    for(step=1;step<=2*n-1;++step){        if(step<=n)l=1,r=step;        else l=step-n+1,r=n;        for(x1=l;x1<=r;++x1)            for(x2=l;x2<=r;++x2){                    if(x1!=x2)f[step][x1][x2]=g[x1][step-x1+1]+g[x2][step-x2+1];                    else f[step][x1][x2]=g[x1][step-x1+1];                    f[step][x1][x2]+=max(f[step-1][x1][x2],f[step-1][x1-1][x2],f[step-1][x1][x2-1],f[step-1][x1-1][x2-1]);                }        }    printf("%lld\n",f[2*n-1][n][n]);}


0 0
原创粉丝点击