欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POJ-3176 Cow Bowling

程序员文章站 2022-07-04 20:06:55
...

Cow Bowling
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 19032   Accepted: 12653

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.

Source

题意:给定一个数塔,从数塔顶端向下走到塔底,问所经过的路径数字之和最大为多少。一道比较经典且入门级的DP问题,此题不能使用贪心,贪心只能得到近似最优解但不一定能够得到最优解。

思路:将数塔略微变形,可以得到一个下半三角矩阵,从数塔低端开始扫描,距离最近的两个数字两两配对求出和,一直向塔顶遍历,由于每次扫描都会求出这一层最大两数之和,所以回到塔顶后塔顶元素dp[0][0]即为所求答案。另外此题也可以使用递归函数解决,去掉塔顶元素,将下方元素分解成两个子塔,逐步划分到子塔的规模小于等于2  ,不过当数组规模过大则会TLE,递归函数无法通过OJ,拿来简单递归练手还是可以的(ノ・ω・)ノ゙

递归版:

POJ-3176 Cow Bowling

a为所求下半三角矩阵,size为当前子塔的规模,line为当前元素行号,offset为当前元素列号

int towerrec(int a[MAX][MAX],int size,int line,int offset)//probably time limit exceeded,tower_rec
{
    if(size<=2)
        return a[line][offset]+max(a[line+1][offset],a[line+1][offset+1]);
    else
        return a[line][offset]+max(towerrec(a,size-1,line+1,offset),towerrec(a,size-1,line+1,offset+1));
}
AC版代码:

#include<iostream>
#define MAX 450
using namespace std;
int towerdp(int a[MAX][MAX],int n)//DP
{
    int i,j;
    int dp[MAX][MAX]={0};
    for(i=n-1;i>=0;i--)
        for(j=0;j<=i;j++)
            dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
    return dp[0][0];
}

int main()
{
    int n;
    int a[MAX][MAX]={0};
    cin >> n;
    int i,j;
    for(i=0;i<n;i++)
        for(j=0;j<=i;j++)
            cin >> a[i][j];
	cout << towerdp(a,n) << endl;
	return 0;
}




相关标签: ACM DP