USACO Section1.5 Number Triangles 解题报告

    numtri解题报告 —— icedream61 博客园(转载请注明出处)
------------------------------------------------------------------------------------------------------------------------------------------------
【题目】
  有一个数字的金字塔,形状如下
        7
       3 8
      8 1 0
     2 7 4 4
    4 5 2 6 5
  要从顶端开始走,每次只能向左下或者右下走,求所经过的数字之和最大值。
【数据范围】
  1<=R<=1000
  0<=每个数<=100
【输入样例】
  5
  7
  3 8
  8 1 0
  2 7 4 4
  4 5 2 6 5
【输出样例】
  30
------------------------------------------------------------------------------------------------------------------------------------------------
【分析】
  DP。
  设num[i][j]为i行j列的数,d[i][j]是从1行1列走到i行j列的当前最优解。
    d[1][1]=num[1][1];
    d[i][j]=0; // i>1 or j>1
  从1行1列走到R行某列的最大值,可以直接递归出来,状态转移方程如下:
    当i==1,j>=2时,d[i][j]=d[i-1][j]+num[i][j];
    当i>=2,j>=2时,d[i][j]=max{d[i-1][j]+num[i][j],d[i-1][j-1]+num[i][j]};
  但本题,递归有边界情况,比较麻烦,递推更方便,状态转移方程如下:
    当i>=2,2<=j<R时
      d[i+1][j]=max{d[i+1][j],d[i][j]+num[i+1][j]};
      d[i+1][j+1]=max{d[i+1][j+1],d[i][j]+num[i+1][j+1]};
  最终,只要扫过d[R][1~R]取得最大值输出即可。
------------------------------------------------------------------------------------------------------------------------------------------------
【总结】
  一遍AC。

------------------------------------------------------------------------------------------------------------------------------------------------

【代码】

 1 /*

 2 ID: icedrea1

 3 PROB: numtri

 4 LANG: C++

 5 */

 6 

 7 #include <iostream>

 8 #include <fstream>

 9 using namespace std;

10 

11 int R;

12 int num[1001][1001],d[1001][1001];

13 

14 void change(int &r,int x) { if(x>r) r=x; }

15 

16 int main()

17 {

18     ifstream in("numtri.in");

19     ofstream out("numtri.out");

20 

21     in>>R;

22     for(int i=1;i<=R;++i)

23         for(int j=1;j<=i;++j) in>>num[i][j];

24 

25     d[1][1]=num[1][1];

26     for(int i=1;i<R;++i)

27         for(int j=1;j<=i;++j)

28         {

29             change(d[i+1][j],d[i][j]+num[i+1][j]);

30             change(d[i+1][j+1],d[i][j]+num[i+1][j+1]);

31         }

32 

33     int maxSum=0;

34     for(int j=1;j<=R;++j) change(maxSum,d[R][j]);

35     out<<maxSum<<endl;

36 

37     in.close();

38     out.close();

39     return 0;

40 }

 

你可能感兴趣的:(number)