传送门:http://poj.org/problem?id=1163
The Triangle
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 49304 | Accepted: 29776 |
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
IOI 1994
题意:在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上每一步都只能往左下走或者右下走。只需求出这个最大和,不必给出具体路径。
首先试了一下递归三角形结果TLE超时了
这个时间复杂度大概为2^n,n=100行估计肯定超时。。。。
这方法差在重复计算了很多。。。
改进:每算出一个MaxSum[r][j]就保存下来。三角形数字整数是n(n+1)/2,则时间复杂度是O(n²)的
数字三角形的记忆化搜索递归AC代码如下:(后面还可优化)
以。进一步考虑,连maxSum数组都可以不要,直接用D的第n行代替maxSum即可。
题意:在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上每一步都只能往左下走或者右下走。只需求出这个最大和,不必给出具体路径。
首先试了一下递归三角形结果TLE超时了
#include<iostream>
#include<algorithm>
#define MAX 101
using namespace std;
int D[MAX][MAX];
int n;
int MaxSum(int i,int j)
{
if(i==n)
return D[i][j];
int x=MaxSum(i+1,j);
int y=MaxSum(i+1,j+1);
return max(x,y)+D[i][j];
}
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin>>D[i][j];
cout<<MaxSum(1,1)<<endl;
}
这个时间复杂度大概为2^n,n=100行估计肯定超时。。。。
这方法差在重复计算了很多。。。
改进:每算出一个MaxSum[r][j]就保存下来。三角形数字整数是n(n+1)/2,则时间复杂度是O(n²)的
数字三角形的记忆化搜索递归AC代码如下:(后面还可优化)
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX];
int n;
int maxSum[MAX][MAX];
int MaxSum(int i,int j)
{
if(maxSum[i][j]!=-1)
return maxSum[i][j];
if(i==n)
maxSum[i][j]=D[i][j];
else
{
int x=MaxSum(i+1,j);
int y=MaxSum(i+1,j+1);
maxSum[i][j]=max(x,y)+D[i][j];
}
return maxSum[i][j];
}
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
{
cin>>D[i][j];
maxSum[i][j]=-1;
}
cout<<MaxSum(1,1)<<endl;
}
递归改成递推:
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX];
int n;
int maxSum[MAX][MAX];
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin>>D[i][j];
for(int i=1;i<=n;++i)
maxSum[n][i]=D[n][i];
for(int i=n-1;i>=1;--i)
for(int j=1;j<=i;++j)
maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j];
cout<<maxSum[1][1]<<endl;
}
空间优化一下,没必要用二维数组maxSum存储每一个MaxSum(r,j),只要从底层每一行向上递推,那么只要一维数组maxSum[100]即可,即只要存储一行的MaxSum值就可
以。进一步考虑,连maxSum数组都可以不要,直接用D的第n行代替maxSum即可。
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX];
int n;
int *maxSum;
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin>>D[i][j];
maxSum=D[n];
for(int i=n-1;i>=1;--i)
for(int j=1;j<=i;++j)
maxSum[j]=max(maxSum[j],maxSum[j+1])+D[i][j];
cout<<maxSum[1]<<endl;
}