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 }

 

posted on 2015-03-09 21:03  IceDream61  阅读(273)  评论(0编辑  收藏  举报

导航