题目来自洛谷P1216,有改动。
IOI1994第一题数字三角形 Number Triangles
题目描述
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
输入格式
第一个行一个正整数 r ,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
输出格式
单独的一行,包含那个可能得到的最大的和。
样例 #1
样例输入 #1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出 #1
30
提示
【数据范围】
对于 100%的数据,1<=1000,所有输入在 0~100范围内。
题目翻译来自NOCOW。
USACO Training Section 1.5
IOI1994 Day1T1
题目解析
非常经典的一道题目,解法有很多
就是数塔那道题
STD1使用DP的方法,从顶端向下搜索
STD1
#include<bits/stdc++.h>
using namespace std;
int n,a[1005][1005],ans;
int main()
{
int r;
cin>>r;
for(int i=1;i<=r;i++) //从上往下DP(其实就是难一点的递推)
{
for(int j=1;j<=i;j++)
{
cin>>a[i][j];
a[i][j]+=max(a[i-1][j-1],a[i-1][j]); //状态转移,a[i][j]代表从顶点走到a[i][j]的最大值
ans=max(ans,a[i][j]); //找最大值
}
}
cout<<ans;
return 0;
}
STD2
从下往上DP
#include<bits/stdc++.h>
using namespace std;
int a[1005][1005];
int main()
{
int r;
cin>>r;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=i;j++)
{
cin>>a[i][j];
}
}
for(int i=r-1;i>=0;i--)
{
for(int j=1;j<=i;j++)
{
a[i][j]+=max(a[i+1][j],a[i+1][j+1]); //状态转移
}
}
cout<<a[1][1];
return 0;
}
以上代码均已AC。
虽然奇葩的解法不少,但上面两个完全够了。
也可以记忆化搜索 懒得写了,有DP谁还用那**玩意