【USACO1.5.1】Number Triangles 数字金字塔
【USACO1.5.1】Number Triangles 数字金字塔
一道动规经典题;
我们可以这样定义状态:
dp[i][j]为从起点出发到dp[i][j]最大所得的和。
难点来了,状态转移方程:
这题我们可以采用逆向思考,因为可以从dp[i-1][j-1]和dp[i-1][j]过来,有要求最大,因此,我们可以列出状态转移方程:
dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+a[i][j];
细节来了;
注意边界条件:
dp[1][1]=a[1][1];
dp[i][1]=dp[i-1][1]+a[i][1];
dp[i][i]=dp[i-1][i-1]+a[i][i];
最后上代码:
知道你们最喜欢
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
int a[1010][1010];
int f[1010][1010];
int ans=INT_MIN;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
scanf("%d",&a[i][j]);
}
}
f[1][1]=a[1][1];
for(int i=2;i<=n;i++){
f[i][1]=f[i-1][1]+a[i][1];
f[i][i]=f[i-1][i-1]+a[i][i];
for(int j=2;j<=i-1;j++){
f[i][j]=max(f[i-1][j-1],f[i-1][j])+a[i][j];
}
}
for(int i=1;i<=n;i++){
ans=max(ans,f[n][i]);
}
printf("%d",ans);
return 0;
}