首页 > 其他 > 详细

POJ3176 Cow Bowling dp

时间:2019-08-03 19:13:56      阅读:68      评论:0      收藏:0      [点我收藏+]

网址:https://vjudge.net/problem/POJ-3176

题意:

给出一个三角形,第$i$行有$i$个数,从第一行出发每次只能到第$i+1$行的第$i$个数或者第$i+1$行的第$i+1$个数,求轨迹上的数的和的最大值。

题解:

$dp[i][j]$指的是到了第i行第j个数的路径上的数的和的最大值。

故从$2$行开始,对于第$i$行的第$j$个数,它的路径只会来自第$i-1$行第$j$个或第$i-1$行的第$j-1$个,故$dp[i][j]=max[dp[i-1][j],dp[i-1][j-1]]+num[i][j]$;即从两条路径中选一条大的路径。枚举$i$从$2$至$n$,然后从$dp[n]$中找出一个最大值即可。

因为第$i$行的状态只和第$i-1$行有关,故使用滚动数组优化。

$dp[i]$为到了某一行的第i个数时路径上的数的和的最大值。

从$2$行开始,对于第$k$行的第$i$个数,它的路径只会来自第$i$个或第$i-1$个,故$dp[j]=max[dp[j],dp[j-1]]+num[j]$;即从两条路径中选一条大的路径。$j$从$k$开始更新到$1$,避免了因为先更新了前面的,在后面处理$dp[j]$的时候重复计算导致错误。

AC代码:(标记的值和题解的说法不一样)

#include <iostream>
#include <algorithm>
using namespace std;
int num[355];
int dp[355];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j <= i; ++j)
			cin >> num[j];
		for (int j = i + 1; j > 0; --j)
			dp[j] = max(dp[j], dp[j - 1]) + num[j - 1];//从上一层到下一层时,只能是从正上方和左上方
		//只与上一层有关,故使用dp[i]和dp[i-1]更新下一层,从后向前更新,因为若从前往后,dp[i-1]将不是上一行的值
	}
	int ans = 0;
	for (int i = 1; i <= n; ++i)
		ans = max(ans, dp[i]);//在最后一行得到最大值
	cout << ans << endl;
	return  0;
}

 

POJ3176 Cow Bowling dp

原文:https://www.cnblogs.com/Aya-Uchida/p/11295801.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!