HNUOJ_10014

The Triangle
Time Limit: 1000ms, Special Time Limit:2000ms, Memory Limit:32768KB
Total submit users: 1348, Accepted users: 1129
Problem 10014 : No special judgement
Problem description
7

3   8

8   1   0

2   7   4   4

4   5   2   6   5



(Figure 1)

Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.


Input
Your program is to read from standard input. The first line contains one integer T, the number of test cases, for each test case: the first line contain a integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99. 
Output
Your program is to write to standard output. The highest sum is written as an integer for each test case one line.
Sample Input
1

5
7
3 8
8 1 0 
2 7 4 4
4 5 2 6 5
Sample Output
30
Problem Source
IOI 1994

简单的动态规划问题

这个最简单的动态规划题目满足了动态规划的四个条件:
1. Characterize the structure of an optimal solution.  有公共的子问题
2. Recursively define the value of an optimal solution.  能递归的定义子问题的最优解
3. Compute the value of an optimal solution in a bottom-up fashion. 能自底向上的求解
4. Construct an optimal solution from computed information.   能通过计算信息构造出最优解


思路:

核心代码如下: 

for(int i=num-2;i>=0;i--){

 for(int j=0;j<=i;j++){

  //该句是整个动态规划的核心

  number[i][j]=Math.max(number[i+1][j],number[i+1][j+1])+number[i][j];

 }

}

试着从下往上找,倒数两行:

  2   7   4   4

4   5   2   6   5
先对最后一行相邻的两个数字进行比较,大的加到上一行的数字上。则4和5比较5较大则倒数第二行2+5;

5和2比较5较大,则倒数第二行7+5,如此类推:则倒数第二行就是:

7   12  10  10;

然后依此类推:直到第一行,就得到了最大的和,当然原题没有要求我们找路径,所以不用记录路径.

其实这就是一种动态规划的应用。


解决问题的代码:

#include
int main()
{
	int i,j,m,n;
	int a[105][105];
	scanf("%d",&m);
	while(m--)
	{
		scanf("%d",&n);
		for(i=0;i=0;i--)
		{
			for(j=0;j<=i;j++)
			{
				a[i][j]+=a[i+1][j]>a[i+1][j+1]?a[i+1][j]:a[i+1][j+1];
				//number[i][j]=Math.max(number[i+1][j],number[i+1][j+1])+number[i][j];
			}
		}
		printf("%d\n",a[0][0]);
	}
	return 0;
}

没有AC的JAVA代码:

import java.util.Scanner;
public class Main{
    public static void main(String []args){
        Scanner scanner=new Scanner(System.in);
        int n;
        n=scanner.nextInt();
        int mar[][]=new int[n+1][n+1];
        for(int i=0;i=0;i--){
            for(int j=0;j<=i;j++){
                max=mar[i+1][j]>mar[i+1][j+1]?mar[i+1][j]:mar[i+1][j+1];
                
                mar[i][j]+=max;
            }
        }
        System.out.println(mar[0][0]);
    }
    
}


你可能感兴趣的:(算法与数据结构)