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;
    }
  • 相关阅读:
    CXF学习(2) helloworld
    foreach与Iterable学习
    java基础之JDBC八:Druid连接池的使用
    java基础之JDBC七:C3P0连接池的使用
    java基础之JDBC六:DBCP 数据库连接池简介
    java基础之JDBC五:批处理简单示例
    java基础之JDBC四:事务简单示例
    java基础之JDBC三:简单工具类的提取及应用
    java基础之JDBC二:原生代码基础应用
    java基础之JDBC一:概述及步骤详解
  • 原文地址:https://www.cnblogs.com/aerer/p/9930917.html
Copyright © 2011-2022 走看看