[刷题笔记] Luogu P1853 投资的最大效益
Solution
刚开始看这道题的时候不自主的想到了纪念品,但其实本题和纪念品还是有区别的。
- 纪念品规定了每次只能买一个纪念品,而本题可以买无限个
- 纪念品需要在原本的基础上买进卖出,钱有进有出,而本题时只有进,稳赚不赔。
本题和纪念品不同的第一点决定了它时完全背包,纪念品是01背包变形。第二点则决定了本题只需要记录最大利息即可,ans初始设置为初始的钱数,每年结束加上最大利息即可。
此外就是个完全背包板子。具体转化如下:
- 把需投资的钱比作重量
- 把利息比作价值
重量每年结束需要更替,替换成原来的金额+上一年的利息。
显然前一年如何不影响后一年的最优解,满足无后效性。以及每一年都可以视作独立的,显然最优方案是将前一年的股票全都出售利滚利投资下一年。符合dp
本题重点需要考虑如何设计状态以及读懂题意,明确与纪念品一题的区别。看出是完全背包,明确每一年互不干扰。处理的时候和纪念品一样具有第一天买第二天早上卖再买再卖不变的特性,这也就决定了我们每次只考虑一天买第二天早上卖,每天都是独立的个体,都是一个状态。
处理的时候包括动态的ans这里借鉴了纪念品一题。
本题还可以在处理下标的时候优化,避免下标过大。由于投资额都是1000的整数,故在处理的过程中都/1000不影响答案。
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 101000
#define INF 0x3f3f3f3f
using namespace std;
int s,n,d;
int ans = 0;
int w[N],v[N];
int f[N];
int main()
{
scanf("%d%d%d",&s,&n,&d);
ans = s;
for(int i=1;i<=d;i++) scanf("%d%d",&w[i],&v[i]);
for(int k=1;k<=n;k++)
{
memset(f,0,sizeof(f));
for(int i=1;i<=d;i++)
{
for(int j = w[i]/1000;j <= ans/1000;j++)
{
f[j] = max(f[j],f[j-w[i]/1000]+v[i]);
}
}
ans += f[ans/1000];
}
cout<<ans<<endl;
return 0;
}
本文作者:SXqwq,转载请注明原文链接:https://www.cnblogs.com/SXqwq/p/17601752.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!