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\n",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\n",m[0][0]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41785863/article/details/83622815