zoukankan      html  css  js  c++  java
  • poj3176-Cow Bowling【dp】

    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.

    Source

    USACO 2005 December Bronze

    思路:这是一道比较简单的动态规划题,有两种方法,其实相差不多都是递推求的。

    第一种:从上到下推,用dp数组来记录,dp[i+1][j]=max(dp[i+1][j],dp[i][j]+m[i+1][j]);
                dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+m[i+1][j+1]);最后将最后一行比较找出最大值即可。

    #include<cstdio>
    #include <iostream>
    using namespace std;
    const int maxn=355;
    int m[maxn][maxn],dp[maxn][maxn];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;++i)
            for(int j=0;j<=i;++j)
                scanf("%d",&m[i][j]);
        dp[0][0]=m[0][0];
        for(int i=0;i<n-1;++i)
            for(int j=0;j<=i;++j)
            {
                dp[i+1][j]=max(dp[i+1][j],dp[i][j]+m[i+1][j]);
                dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+m[i+1][j+1]);
            }
        int sum=dp[n-1][0];
        for(int i=0;i<n;++i)
            sum=max(sum,dp[n-1][i]);
        printf("%d
    ",sum);
        return 0;
    }
    

    第二种:从下往上推,每个位置都从下边两个位置中选一个大的相加,这样一直往上,直到m[0][0],就求出来了。

    #include<cstdio>
    #include <iostream>
    using namespace std;
    const int maxn=355;
    int m[maxn][maxn];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;++i)
            for(int j=0;j<=i;++j)
                scanf("%d",&m[i][j]);
        for(int i=n-2;i>=0;--i)
            for(int j=0;j<=i;++j)
                m[i][j]+=max(m[i+1][j],m[i+1][j+1]);
        printf("%d
    ",m[0][0]);
        return 0;
    }
  • 相关阅读:
    API接口智能化测试探索与实践
    程序员的社会地位
    程序员五六年能存100万,你说你焦虑个啥!!!
    苹果公司宣布:公司内部的员工有权讨论自己的工作条件和薪酬
    男子股票账户突然多了一个亿!结果……
    你选择双休还是单休?
    PAL制式和NTSC制式的定义及区别(转)
    javascript入门系列演示·三种弹出对话框的用法实例(转)
    sink相关
    Ubuntu下安装gsteditor
  • 原文地址:https://www.cnblogs.com/aerer/p/9930917.html
Copyright © 2011-2022 走看看