【动态规划】 Little Sub and Piggybank

【动态规划】 Little Sub and Piggybank目录 动态规划 LittleSuband

【动态规划】 Little Sub and Piggybank

Problem

Input

Output

Please output an integer in one line, indicating the maximum happiness that Little Sub can achieve.

Sample Input

4 0 2 4 1 0 4 3 1

Sample Output

5

Solution

你有一个piggybank小猪存钱罐。你在每天的开始都可以向piggybank中放入任意数量的钱,只要放的不比前一天多就行。第一天可以放入任何数量的钱。每天超市都有一个物品,第i天的物品价格为w[i],购买后得到的愉悦度为v[i]。但是你只有在piggybank中的钱刚好等于w[i]时,才可以买入第i天的物品,买完之后你的钱包就空了。问到第n天,能够获得最大愉悦度是多少。

dp[i][j] 表示当前购买的是i物品,前一个是j物品的最大愉悦度。
显然有转移方程 dp[i][j] = max(dp[j][k] + v[i])
因为v[i]是定值,所以又可以写成dp[i][j] = max(dp[j][k]) + v[i]
如果对于给定的ij,枚举k来找max(dp[j][k])的话,时间复杂度会达到\(O(n^3)\)
因此我们可以令mx[j][k]表示购买了第j个物品,且购买第j个物品之前购买的一个物品在kj之间的最大愉悦度。
于是转移方程就可以写成dp[i][j] = mx[j][k] + v[i]










如果你尝试了\(O(n^3)\)的暴力写法,你就会知道不是所有的k都可以进行状态转移的。因为题目要求每天放入piggybank的钱的数量不能大于前一天放入的数量。所以在ij确定的情况下,从第j天到第i天放入的钱的数量已经确定,而在第j天放入钱数的最小值应该大于\(\frac{w[i]}{i-j}\)
\(\frac{w[j]}{j-k} >= \frac{w[i]}{i-j}\)
移项可以得到 \(k >= j – \frac{w[j]}{w[i]}(i-j)\) ,即为k的最小值。




而如何维护mx[i][j]数组呢?
可以在枚举i的时候用已知的dp[i][j]更新。
mx[i][j] = max(mx[i][j+1], dp[i][j]);




最后可以用max(mx[i][0])更新答案。

Code

#include 
    
      using namespace std; typedef long long ll; const int MAXN = 2005; ll w[MAXN],v[MAXN]; ll dp[MAXN][MAXN],mx[MAXN][MAXN]; int main() { int n; scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%lld",w+i); for(int i = 1; i <= n; i++) scanf("%lld",v+i); ll ans = 0; //本题中让输入数据的下标从1开始,0空出来看作一个必买入的无价值物品,方便数组的表示。 for(int i = 1; i <= n; i++) { dp[i][0] = v[i]; for(int j = 1; j < i; j++) { int k = ((w[i] == 0) ? 0 : (int)max(ceil(j - 1.0*w[j]/w[i]*(i-j)),0.0)); if(mx[j][k]) dp[i][j] = mx[j][k] + v[i]; //mx[j][k] == 0 说明不往piggybank中放钱了 } for(int j = i - 1; j >= 0; j--) { mx[i][j] = max(mx[i][j+1], dp[i][j]); } } for(int i = 1; i <= n; i++) { ans = max(ans, mx[i][0]); } printf("%lld\n",ans); return 0; } 
    

转载于:https://www.cnblogs.com/NeilThang/p/10809730.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/219913.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午9:35
下一篇 2026年3月17日 下午9:36


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号