zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    《驱动学习
    《海思3521D
    《uboot网卡驱动分析》
    《驱动学习
    《驱动学习
    《驱动学习
    对应第一篇文章api的编写
    Dot模板的使用小结2
    项目代码摘抄,dot的用法之1
    文字的默认基线是底部对齐的
  • 原文地址:https://www.cnblogs.com/icedream61/p/4324504.html
Copyright © 2011-2022 走看看