The Triangle POJ - 1163

7
3   8
8   1   0
2   7   4   4
4   5   2   6   5

(Figure 1)

Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.

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

这道题比较简单,经典DP中的数字三角形问题,但是有两个需要注意的地方:1,三角形的存储,注意边界问题,即你从0还是1开始存储。2,动态规划它解决这种问题的方式一般是自底向上,所以注意i循环,傻逼的我当时找错误找了好久,原因是j--,我自己写成了j++,干啥一定要细心,不要犯这种低级错误。3.动态规划方程应该都会吧----(默认都会)哈哈哈,不会的可以看紫书,动规第一个例子就讲的是这个:

每次有两种选择——左下和右下,一个n层数字三角形的完整路线有2^n-1条,当n很大时回溯法的速度会特别慢。

把当前的位置(i,j)看成一个状态,然后定义状态(i,j)的指标函数d(i,j)为从格子(i,j)出发时能得到的最大和,不同状态之间是如何转移的?从格子(i,j)出发有两种决策,如果往左走,则走到(i+1,j)后需要求从(i+1,j)出发后能得到的最大和这一问题,

如果往右走,则走到(i+1,j+1)后需要求从(i+1,j+1)出发后能得到的最大和这一问题,由于在这两个决策中自由选择,所以应选择d(i+1,j)和d(i+1,j+1)中较大的一个。

所以状态转移方程为:d(i,j)=a(i,j)+max{d(i+1,j),d(i+1,j+1)}.

很简单,注意最后的输出结果是最顶部的元素。看你是从1还是0开始存,不同的对应结果不同。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=101;
int dp[maxn][maxn];
int main()
{
  int n;
  while(cin>>n&&n!=0)
  {
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
    {
      for(int j=1;j<=i;j++)
      {
        cin>>dp[i][j];
      }
    }
    for(int i=n-1;i>=1;i--)
    {
      for(int j=1;j<=i;j++)
      {
        dp[i][j]=dp[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
      }
    }
    cout<<dp[1][1]<<endl;
  }
  return 0;
}


 

猜你喜欢

转载自blog.csdn.net/cjh1459463496/article/details/88957034