【USACO TRAINING】数字金字塔

来源:互联网 发布:ubuntu安装哪个版本好 编辑:程序博客网 时间:2024/06/05 00:09

【USACO TRAINING】数字金字塔

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

题目描述

考虑在下面被显示的数字金字塔。 写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大。每一步可以走到左下方的点也可以到达右下方的点。

 

在上面的样例中,从7 到 3 到 8 到 7 到 5 的路径产生了最大和:30

输入

第1行:1个整数R(1<= R<=1000),表示行的数目。

接下来共R行,第i行有i个整数。所有的数均非负的且不大于100。

输出

第1行:可以得到的最大的和。

样例输入

573 88 1 02 7 4 44 5 2 6 5 

样例输出

30


是一道dp的裸题。。也是作为dp复习的开始。
f[i,j]=max{f[i-1][j],f[i-1][j-1]}+g[i][j](g[i][j]为原位置的值,f[i][j]为自顶而下路径所得的最大值)
填表法:
#include<cstdio>int an[1001][1001];int main(){    int n,i,j,p=1,t;    scanf("%d",&n);    for(i=0;i<n;i++,p++)        for(j=0;j<p;j++)            scanf("%d",&an[i][j]);    for(i=1,p=1;i<n;i++,p++)        for(j=0;j<=p;j++)        {            if(j==p){an[i][j]+=an[i-1][j-1];continue;}            if(j>0)            {                if(an[i-1][j-1]>an[i-1][j])an[i][j]+=an[i-1][j-1];                else an[i][j]+=an[i-1][j];            }            else an[i][j]+=an[i-1][j];        }    t=an[n-1][0];    for(i=1;i<p;i++)        if(an[n-1][i]>t)t=an[n-1][i];    printf("%d\n",t);}

记忆化搜索:
#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<map>#define INF 0x3f3f3f3f#define LL long long intLL 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 ans[1010][1010],n;bool s[1010][1010];LL dfs(int i,int j){    if(s[i][j]||i==n)return ans[i][j];    ans[i][j]=ans[i][j]+max(dfs(i+1,j),dfs(i+1,j+1));    s[i][j]=1;    return ans[i][j];}int main(){    int i,j;n=getint();    for(i=1;i<=n;++i)        for(j=1;j<=i;++j)            ans[i][j]=getint();    printf("%lld\n",dfs(1,1));}</span><span style="font-size:18px;"></span>
刷表法:
#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<stack>#include<queue>#include<vector>#include<map>#define INF 0x3f3f3f3f#define LL long long intLL 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 ans[1010][1010],n,g[1010][1010];int main(){    int i,j;n=getint();    for(i=1;i<=n;++i)        for(j=1;j<=i;++j)            g[i][j]=getint();    for(i=1;i<=n;++i)        ans[n][i]=g[n][i];    for(i=n;i>1;--i)        for(j=1;j<=i;++j){            if(j<i)ans[i-1][j]=max(ans[i-1][j],g[i-1][j]+ans[i][j]);            if(j>1)ans[i-1][j-1]=max(ans[i-1][j-1],g[i-1][j-1]+ans[i][j]);        }    printf("%lld\n",ans[1][1]);}


1 0
原创粉丝点击