关闭

poj 1163解题报告(动态规划)

187人阅读 评论(0) 收藏 举报
//要求输入一个组阶梯数,求从顶层到最底层的最大和,每个连接只能为该层数字到下层左下数字或右下数字的路径。
  	  7
	3   8
      8   1   0
    2   7   4   4
  4   5   2   6   5
//最大和路径为 7,3,8,7,5之和为30
//思路:maxsum[i,j]为第i行,第j个数的最大和,tr[i,j]为第i行第j个数
//maxsum[i,j]=max(maxsum[i-1,j-1]+tr[i-1,j-1],maxsum[i-1,j]+tr[i-1,j])
//最后的结果就为第N行的所有最大和中最大的一个。
#include <iostream>
using namespace std;
short tr[5051],maxsum[5051];
int main()
{
	int N;
	cin>>N;
	for(int i=1;i<=N*(N+1)/2;++i)
	{
		cin>>tr[i];
	}
	/*for(int i=1;i<=N*(N+1)/2;++i)
	{
	cout<<tr[i]<<" ";
	}*/
	maxsum[0]=0;
	tr[0]=0;
	maxsum[1]=tr[1];
	if (N==1)
	{
		cout<<maxsum[1];
		return 0;
	}

	for (int i=2;i<=N;++i)
	{
		for (int j=1;j<=i;++j)
		{
			if (j==1)
			{
				maxsum[i*(i-1)/2+j]=maxsum[i*(i-1)/2-(i-2)]+tr[i*(i-1)/2+j];   //当为每行第一个数时,只能有上一行的第一个数得到
			}
			else if(j==i)
			{
				maxsum[i*(i-1)/2+j]=maxsum[i*(i-1)/2]+tr[i*(i-1)/2+j];   //每行最后一个数也只能由上一行的最后一个数得到
			}
			else
			{
				if(maxsum[(i-2)*(i-1)/2+j-1]>maxsum[(i-2)*(i-1)/2+j])
				{
					maxsum[i*(i-1)/2+j]=maxsum[(i-2)*(i-1)/2+j-1]+tr[i*(i-1)/2+j];
				}
				else
				{
					maxsum[i*(i-1)/2+j]=maxsum[(i-2)*(i-1)/2+j]+tr[i*(i-1)/2+j];
				}
			}
			
		}
	}
	/*for (int i=1;i<=N;++i)
	{
		for (int j=1;j<=i;++j)
		{
			cout<<maxsum[i*(i-1)/2+j]<<" ";
		}
		cout<<endl;
	}*/
	int max_sum=0;
	for (int j=1;j<=N;++j)
	{
		if (maxsum[N*(N-1)/2+j]>max_sum)
		{
			max_sum=maxsum[N*(N-1)/2+j];

		}
	}
	cout<<max_sum;
	return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4395次
    • 积分:79
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档