题目:
The Triangle
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 36792 | Accepted: 22034 |
Description
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1)
Input
Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.
Output
Your program is to write to standard output. The highest sum is written as an integer.
Sample Input
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
Sample Output
30
Source
题意:
在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。
三角形的行数大于1小于等于100,数字为0 -99
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
先来看看由下至上的解法:
由下至上算最大值时,思路很简单。
由下至上选择时,把大三角形看成只有三个数的小三角形,把小三角形的定点加上小三角形中数值最大的支点的和作为下一次的支点,层层递归即可
#include <iostream>
#include <cstdio>
using namespace std;
const int maxx=100+10;
int map[maxx][maxx];
int n;
int i,j;
int max(int x,int y)
{
return x>y?x:y;
}
int dp( )
{
for(i=n-1;i>=1;i--)
{
for(j=1;j<=i;j++)
{
map[i][j]=max(map[i+1][j],map[i+1][j+1])+map[i][j];///由下至上选择时,把大三角形看成只有三个数的小三角形,把小三角形的定点加上小三角形中数值最大的支点的和作为下一次的支点,层层递归即可
}
}
return map[1][1];
}
int main( )
{
cin>>n;
for(i = 1;i <= n; i++)
{
for(j=1;j <= i; j++)
{
scanf("%d",&map[i][j]);///当输入的数据很大时,不要用cin 输入,cin 输入是很慢的,因为cin其实是个函数,他在输入的时候会自动匹配所输入数据的格式,匹配成功后才能输入,你可以想象每个输入的数据都要在一个函数中先扫一遍才能输入,这可以有多慢吗?但其实scanf不是最快的,更快的还有getchar,但大多数题目是不要求进行太深的读入优化的
}
}
cout<<dp()<<endl;
return 0;
}
如果是由上至下,那么就应该进行递归求解。
而且,在递归过程中必须做好标记,对已经求解出来的数进行记录,避免重复计算。
其实如果仔细看这个由上至下的递归,我们会发现,其实,他的本质也是由下至上DP的。
#include <iostream>
#include <cstdio>
using namespace std;
const int maxx=100+10;
int map[maxx][maxx];
int vis[maxx][maxx];
int n;
int i,j;
int max(int x,int y)
{
return x>y?x:y;
}
int dp(int x,int y)
{
if(vis[x][y]!=-1)
{
return vis[x][y];
}
if(x==n)
{
vis[x][y]=map[x][y];
}
else
{
int kx=dp(x+1,y);
int ky=dp(x+1,y+1);
vis[x][y]=max(kx,ky)+map[x][y];
}
return vis[x][y];
}
int main( )
{
cin>>n;
for(i = 1;i <= n; i++)
{
for(j=1;j <= i; j++)
{
scanf("%d",&map[i][j]);
vis[i][j]=-1;
}
}
cout<<dp(1,1)<<endl;
return 0;
}
如有BUG请指出,不胜感激。。。。。。