Problem:17
Time Limit:1000ms
Memory Limit:65536K
Description
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的那个数或者右边的那个数。
Input
输入数据有多组,每组输入的是一行是一个整数N (1 < N <= 100),给出三角形的行数。下面的N行给出数字三角形。数字三角形上的数的范围都在0和100之间。
Output
输出最大的和。
Sample Input
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
3
1
2 3
1 1 1
Sample Output
30
5
这是一个动态规划问题,但是由于题目语言的问题导致没接触过这种题的人很难理解题意,我开始就一直理解不了这个路径到底是怎么走的,30怎么也想不出来是咋得出来的。
正确理解:两个选择,向下或者右下。
思路:把当前位置(i,j)看成一个状态,找(i+1,j)和(i+1,j+1)中最大的那个,但是要考虑边界。
#include
using namespace std;
int main()
{
ios::sync_with_stdio(0);
int n,a[105][105];
while(cin>>n)
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
cin>>a[i][j];
for(int i=2;i<=n;i++)
for(int j=1;j<=i;j++)
{
if(j==1)a[i][j]=a[i][j]+a[i-1][j];
else if(j==i)a[i][j]=a[i][j]+a[i-1][j-1];
else a[i][j]=a[i][j]+max(a[i-1][j],a[i-1][j-1]);
}
int max1=0;
for(int i=1;i<=n;i++) max1=max(max1,a[n][i]);
cout<<max1<<endl;
}
return 0;
}
还有一种方法是看的大佬的,从下往上走
#include
using namespace std;
int main()
{
ios::sync_with_stdio(0);
int n,a[105][105];
while(cin>>n)
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
cin>>a[i][j];
for(i=n-1;i>=1;i--)
{
for(j=1;j<=i;j++)
{
a[i][j]=a[i][j]+max(a[i+1][j],a[i+1][j+1]);
}
}
cout<<a[1][1]<<endl;
}
}
return 0;
}