zoukankan      html  css  js  c++  java
  • 【原】 POJ 3176 Cow Bowling 动态规划 解题报告

    http://poj.org/problem?id=3176

    方法:
    DP:将大问题转化为小问题解决。由递归写循环。
    c[i][j]表示从a[1][1]开始到a[i][j]的最大和。而最终的结果为c[n][1...n]中的最大值
    递归式为:
    c[1][1] = a[1][1]
    c[i][j] = max{ c[i-1][j-1], c[i-1][j] } + a[i][j]
    maxsum = argmax(j){ c[n][1...n] }

    <1>最优子结构:如果c[i][j]是从a[1][1]开始到a[i][j]的最大和,那么c[i-1][j-1]和c[i-1][j]也
                   是到a[i-1][j-1]和a[i-1][j]的最大和。
    证明:设maxsum[i]=k是从a[1][1]开始到a[i][j]的最大和,则c[i][j]=k。
          当c[i-1][j-1]>c[i-1][j]时:
          c[i][j]=c[i-1][j-1]+a[i][j],因此k-a[i][j]为从a[1][1]开始到a[i-1][j-1]的一条路径长。
          下面要证明k-a[i][j]为从a[1][1]到a[i-1][j-1]的最大值。
          设w是一条从a[1][1]到a[i-1][j-1]更大的路径,|w|>k-a[i][j]。然后cut and past,则从
          a[1][1]开始到a[i][j]的一条更长的路径为w||a[i][j],此时该路径值大于k。与假设相矛盾,
          所以c[i-1][j-1]=a[i][j]
          当c[i-1][j-1]<c[i-1][j]时的情况可以同样得证。

    <2>Overlapping:例如i=6,j=7
                    (6,7)
                   /     \
                  /       \
               (5,6)     (5,7)
                /\         /\
               /  \       /  \
            (4,5)(4,6) (4,6)(4,7)

    可以发现(4,6)之后的子树有重叠产生

    另一种dp:从下往上递推
    c[i][j]表示由a[i][j]开始到三角形最底部的最大路径。最终结果为c[1][1]
    递归式:
    c[n][1...n] = a[n][1...n]
    c[i][j] = max{ c[i+1][j] , c[i+1][j+1] } + a[i][j]

    Description

    The cows don't use actual bowling balls when they go bowling. They each take a number (in the range 0..99), though, and line up in a standard bowling-pin-like triangle like this:

    7

    3 8

    8 1 0

    2 7 4 4

    4 5 2 6 5

    Then the other cows traverse the triangle starting from its tip and moving "down" to one of the two diagonally adjacent cows until the "bottom" row is reached. The cow's score is the sum of the numbers of the cows visited along the way. The cow with the highest score wins that frame. 
    Given a triangle with N (1 <= N <= 350) rows, determine the highest possible sum achievable.

    Input

    Line 1: A single integer, N 
    Lines 2..N+1: Line i+1 contains i space-separated integers that represent row i of the triangle.

    Output

    Line 1: The largest sum achievable using the traversal rules

    Sample Input

    5

    7

    3 8

    8 1 0

    2 7 4 4

    4 5 2 6 5

    Sample Output

    30

    Hint

    Explanation of the sample:

    7

    *

    3 8

    *

    8 1 0

    *

    2 7 4 4

    *

    4 5 2 6 5

    The highest score is achievable by traversing the cows as shown above.

       1: #include <stdio.h>
       2: #include <iostream>
       3:  
       4: using namespace std ;
       5:  
       6: const int N = 351 ;
       7:  
       8: int a[N][N] ;
       9: int c[N][N] ;
      10:  
      11: //dp方法1
      12: void run3176()
      13: {
      14:     int n ;
      15:     int i,j ;
      16:     int maxc ;
      17:     int max ;
      18:  
      19:     scanf( "%d", &n ) ;
      20:     for( i=1 ; i<=n ; ++i )
      21:     {
      22:         c[i][0] = 0 ; //****
      23:         for( j=1 ; j<=i ; ++j )
      24:             scanf( "%d", &(a[i][j]) ) ;
      25:     }
      26:  
      27:     //***
      28:     c[1][1] = a[1][1] ;
      29:     for( i=2 ; i<=n ; ++i )
      30:     {
      31:         for( j=1 ; j<=i ; ++j )
      32:             c[i][j] = std::max( c[i-1][j-1], c[i-1][j] ) + a[i][j] ;
      33:     }
      34:  
      35:     max = c[n][1];
      36:     for( i=2 ; i<=n ; ++i )
      37:         max = max>c[n][i] ? max : c[n][i] ;
      38:  
      39:     printf( "%d\n", max ) ;
      40: }
      41:  
      42: //dp方法2:从下往上递推
      43: void run1163_2()
      44: {
      45:     int n ;
      46:     int i,j ;
      47:  
      48:     scanf( "%d", &n ) ;
      49:     for( i=1 ; i<=n-1 ; ++i )
      50:     {
      51:         for( j=1 ; j<=i ; ++j )
      52:             scanf( "%d", &(a[i][j]) ) ;
      53:     }
      54:  
      55:     for( j=1 ; j<=n ; ++j )
      56:     {
      57:         scanf( "%d", &(a[n][j]) ) ;
      58:         c[n][j] = a[n][j] ;
      59:     }
      60:  
      61:     for( i=n-1 ; i>=1 ; --i )
      62:     {
      63:         for( j=1 ; j<=i ; ++j )
      64:             c[i][j] = std::max( c[i+1][j] , c[i+1][j+1] ) + a[i][j] ;
      65:     }
      66:  
      67:     printf( "%d\n" , c[1][1] ) ;
      68: }

    如果您满意我的博客,请点击“订阅Allen Sun的技术博客”即可订阅,谢谢:)

    原创文章属于Allen Sun
    欢迎转载,但请注明文章作者Allen Sun和链接
  • 相关阅读:
    Linux各目录及每个目录的详细介绍
    centos7 + mysql5.7 tar包解压安装
    Hive2.0的新特性介绍
    Hadoop HIVE
    PIG执行MR时报Connection refused错误
    Zookeeper启动Permission denied
    Hadoop Pig
    Hadoop组件之-HDFS(HA实现细节)
    Datanode启动问题 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for Block pool <registering>
    HDFS Federation
  • 原文地址:https://www.cnblogs.com/allensun/p/1872058.html
Copyright © 2011-2022 走看看