zoukankan      html  css  js  c++  java
  • POJ3176 Cow Bowling dp

    网址: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;
    }
    
  • 相关阅读:
    java基础练习 4
    java基础练习 5
    java基础练习 3
    java基础练习 2
    二级联动菜单动态刷新下拉列表的一种实现方法
    疯狂Java讲义笔记(二)
    Windows10 Internet Explorer已停止工作的解决方法
    Git笔记
    Spring Boot笔记
    maven笔记
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/11295801.html
Copyright © 2011-2022 走看看