USACO Training Section 1.5 Number Triangles

相当基本的动态规划。第i行第j列可得到的最大的和为sum(i,j)(1<=j<=i),则
sum(i,j)=node(i,j)+ max(sum(i-1,j),sum(i-1,j-1)) . 注意由于数值为三角形,故有些值没有定义。在本题中可简单的用0来替代。这样,使用一个矩阵来存储和计算sum,是最简易的方法。而事实上只需要数组用O(n)空间就可以做这个计算了,因为我们不需要记录计算路径,只需要输出计算结果。

上面的思路是从顶往下DP,也可以从底至上计算,这样可以不用保存最大值。缺点是必须记录所有的数,空间复杂度较高。不过对于本题而言,不用在意。

最后实现用的最节省空间的方式,滚动数组(注意pre_sum)。注意其中首先读入sum[0]可避免对line==0时保存sum[line]的特殊处理。

原题链接:
http://ace.delos.com/usacoprob2?a=sagomFwQFqE&S=numtri
/*
ID: blackco3
TASK: numtri
LANG: C++
*/
#include <fstream>
using namespace std;
#define _max_ 1000
int main()
{	
	ifstream fin("numtri.in");
	int n_line, sum[_max_] ;
	fin >> n_line >> sum[0] ;
	int node_val, cur_sum, pre_sum, max_sum=0 ;
	for(int line=1; line<n_line; line++ ){
		for( int col=0; col<=line; col++ ){
			fin >> node_val ;
			if( !col ){
				cur_sum = node_val + sum[col] ;
			} else {
				if( col==line ) {
					cur_sum = node_val + sum[line-1] ;
					sum[line] = cur_sum ;
				} else {
					cur_sum = node_val + ( sum[col-1]>sum[col] ? sum[col-1] : sum[col] ) ;
				}
				sum[col-1]=pre_sum ;
			}			
			max_sum = max_sum >= cur_sum ? max_sum : cur_sum ;
			pre_sum = cur_sum ;
		}
	}
	ofstream fout("numtri.out");
	fout << max_sum << endl ;
	return 0;
}

你可能感兴趣的:(C++,c,C#,J#)