洛谷 P1853【投资的最大效益】

洛谷P1853 投资的最大效益 动态规划 题目 多重背包,不过要多考虑一个年限,最开始用map复杂度太高,改用数组顶着优化勉强过了。 本金为背包空间,投资额为消耗的空间,利息为价值 #pragma GCC optimize(3) #pragma GCC optimize("Ofast", "inline") #include <iostream> #include <cstdio> #include <cma... 阅读详情

原题链接

思路:

  • 不难看出是完全背包类问题,只是要明确一点,“花钱”买债券所花的钱并没有真正的花出去,关键就在于随时都可以卖出任何所持有的债券。那么,实际上我们可以认为每一年都先把所有持有的债券变卖套现,然后拿着全部的现金重新购买债券(重新打背包),寻找能够获得的最多的金钱。
  • 明白了这一点,就可以写出最简单的一版答案。dp【】记录 j 金钱能够获得的最多的本金+利润。注意答案是最后能到达的最大背包容量。

代码+讲解:

一:

  • 状态转移方程:
​while(m--){
        for(int i=1;i<=n;i++){
            for(int j=w[i];j<=W;j++){
                dp[j] = max(dp[j] , dp[j-w[i]] + w[i] + v[i]);
            }
        }
        W = dp[W];
}
  • 完整代码1(无优化,记录本金加利息:4099ms,39956KB)
​//4099ms, 39956KB 


#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn = 15;
const int maxw = 10000005;

int w[maxn],v[maxn];
int dp[maxw];

int main(){
    int W,m,n;
    cin>>W>>m>>n;//m years
    for(int i=1;i<=maxw;i++)
        dp[i] = i;
    for(int i=1;i<=n;i++)
        cin>>w[i]>>v[i];
    while(m--){
        for(int i=1;i<=n;i++){
            for(int j=w[i];j<=W;j++){
                dp[j] = max(dp[j] , dp[j-w[i]] + w[i] + v[i]);
            }
        }
        W = dp[W];
    }
    cout<<W<<endl;
    return 0;
}​
  • 核心:

    因为 dp[j] 表示花 j 金钱能够获得的本金+最大利润,所以初始化条件有些特殊。
​for(int i=1;i<=maxw;i++)
        dp[i] = i;​

二:

  • 状态转移方程:
    在这版代码中,由于 dp[j] 仅代表所获利润,因此每次更新的 W 也只做循环边界使用。
​while(m--){
        for(int i=1;i<=n;i++){
            for(int j=w[i];j<=W;j++){
                dp[j] = max(dp[j] , dp[j-w[i]] + v[i]);
            }
        }
        W += dp[W];
}
  • 完整代码2(只记录利息,略微简化计算:3508ms,39864KB)
​//3508ms, 39864KB 


#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn = 15;
const int maxw = 10000005;

int w[maxn],v[maxn];
int dp[maxw];

int main(){
    int W,m,n;
    cin>>W>>m>>n;//m years
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
        cin>>w[i]>>v[i];
    while(m--){
        for(int i=1;i<=n;i++){
            for(int j=w[i];j<=W;j++){
                dp[j] = max(dp[j] , dp[j-w[i]] + v[i]);
            }
        }
        W += dp[W];
    }
    cout<<W<<endl;
    return 0;
}​

三:

  • 状态转移方程:
    因为债券售价千元起步,所以当我们拥有 j 金钱时,实际能够起作用的只有 j/1000*1000 这么多。故使用 dp[j] 记录当我们拥有的金钱在 [ j,j+1000 ) 区间时,能够获得的最大利润。其实质就是减少了打表时多达几千次的冗余操作。
​ while(m--){
        for(int i=1;i<=n;i++){
            for(int j=w[i];j<=W/1000*1000;j+=1000){
                dp[j] = max(dp[j] , dp[j-w[i]] + v[i]);
            }
        }
        W += dp[W/1000*1000];
}
  • 完整代码3(减少打表次数:268ms,39944KB)
​//268ms, 39944KB 


#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn = 15;
const int maxw = 10000005;

int w[maxn],v[maxn];
int dp[maxw];

int main(){
    int W,m,n;
    cin>>W>>m>>n;//m years
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
        cin>>w[i]>>v[i];
    while(m--){
        for(int i=1;i<=n;i++){
            for(int j=w[i];j<=W/1000*1000;j+=1000){
                dp[j] = max(dp[j] , dp[j-w[i]] + v[i]);
            }
        }
        W += dp[W/1000*1000];
    }
    cout<<W<<endl;
    return 0;
}​

四:

  • 状态转移方程:
    既然我们知道只需要打整千钱数的背包,何不删去无用空间的背包,减少空间复杂度。我们可以使用 dp[j] 表示钱数仅大于 j*1000 时所能获得的最大利润。
​while(m--){
	for(int i=1;i<=n;i++){
		for(int j=w[i];j<=W/1000;j++){
			//int t = j + dp[j]/1000;
			dp[j] = max(dp[j] , dp[j-w[i]] + v[i]);
		}
	}
	W += dp[W/1000];
}
  • 注意代码中的注释行,这里我陷入了动态规划问题初学者常触的误区,是对动态规划算法的时间性还不够敏感所致。这里写出为什么算法中没有 t 的参与。首先, dp[j] 代表在前一年结束后,j 本金(前一年的本金)所能获得的最大利润。其次,在完全背包的循环条件下,dp[ j - w[i] ] 代表今年结束后,使用 j 本金(今年的本金)所能获得的最大利润。若将 dp[ j - w[i] ] 改成 dp[ t - w[i] ],显然是不对的,因为 t 实际上是默认完全执行上一年的方案,这不符合动态规划思想。
  • 完整代码4(时空复杂度均得到优化:35ms,1052KB)
​//35ms, 1052KB 


#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn = 15;
const int maxw = 10005;

int w[maxn],v[maxn];
int dp[maxw];

int main(){
	int W,m,n;
	cin>>W>>m>>n;//m years
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;i++){
		cin>>w[i]>>v[i];
		w[i]/=1000;
	}
	while(m--){
		for(int i=1;i<=n;i++){
			for(int j=w[i];j<=W/1000;j++){
				//int t = j + dp[j]/1000;
				dp[j] = max(dp[j] , dp[j-w[i]] + v[i]);
			}
		}
		W += dp[W/1000];
	}
	cout<<W<<endl;
	return 0;
}​
Ubuntu20.04安装Ceres库 ceres真难安装。 阅读详情

相关推荐

遗传病变异注释预测工具安装系列之------Exomiser 安装及bug处理

Exomiser是一个Java程序,它从全外显子组或全基因组测序数据中发现潜在的致病变异。 Java 版本必须为1.8以上。 Exomiser 最新版本下载 wget -c https://github.com/exomiser/Exomiser/releases/download/11.0.0/exomiser-cli-11.0.0-distribution.zip unzip ...

qq_37329349的博客 1535

洛谷:P1853 【投资的最大效益】

题目背景 约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。 题目描述 例如:有如下两种不同的债券:①投资额$4000,年利息$400;②投资额$3000,年...

修电缆的建筑工的博客 642

Unity UI Toolkit避坑指南:从官方Samples到实际项目,这些‘坑’我帮你踩过了

本文分享了Unity UI Toolkit在实际项目中的避坑经验和优化技巧,包括动画系统的高效替代方案、3D世界UI的创新实现方式、USS样式继承的反直觉规则等。通过详细的代码示例和性能优化策略,帮助开发者避免常见陷阱,提升开发效率。

weixin_29535577的博客 343

洛谷 P1853 - 投资的最大效益

题目描述 P1853 投资的最大效益 解法:完全背包 唯一和完全背包问题不同就是,总金额的数目是在变动的,因此,我们在完全背包问题循环的外面再套上一层循环用于更新总金额 #include <bits/stdc++.h> using namespace std; struct bond{ int w, c; }; int main() { bond bo[51]; ...

Aries_young的博客 501

MySQL8.2.0下载安装

4、点击No thanks,just start my download,就是只是开始下载的意思,点击下载,等待下载完成。5、新建空白行,或直接双击紧挨的空白行,把复制的mysql的安装路径bin路径复制粘贴过来,确定,确定,确定。1、上面点击finish后,自动勾选了run mysql配置,自动会打开配置页面,点击Next。1、双击安装包,进入安装流程,勾选我同意 I accept,next。2、根据自己需要选择,我选的第二个,可以自己改安装路径。2、默认,点击Next,记住默认端口3306。

m0_59681797的博客 1万+

低供电电压CMOS偏置电路分析(有些类似于三支路电流源)

1、偏置电路原理图以及仿真结果 电路电流分析:Ip=Ip1=Ip2=Ip3,那么 Ip=12μnCoxWL(IpR−VTH)2 I_p=\frac{1}{2} μ_nC_{ox}\frac{W}{L} (I_{p}R-V_{TH})^2 Ip​=21​μn​Cox​LW​(Ip​R−VTH​)2 解出方程式即可得到参考电流及参考电压 2、电路电源抑制比PSRR分析 这里为了方便,小信号前都不加△ 首先做一个近似,由于gmRo>>1,直接将VDD变化导致的P3管漏级电压变化与VDD变化量做相等

qq_46579389的博客 2910

打卡信奥刷题(90)用Scratch图形化工具信奥P1853 [普及组] 投资的最大效益

约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。

Loge谈信奥--一个专注于信奥人的博客 2221

PCA9548实战:从硬件连接到Linux驱动的I2C扩展全解析

本文详细解析了PCA9548 I2C多路复用器从硬件连接到Linux驱动配置的全过程。涵盖硬件引脚连接、电源去耦、地址选择等关键设计要点,以及Linux驱动加载、设备树配置和应用层编程技巧,帮助开发者高效实现I2C总线扩展。

weixin_28726391的博客 410

(完全背包)洛谷P1853投资的最大效益

洛谷P1853投资的最大效益 思路: 完全背包,用dp[i]表示本金为i时下一年获得的收益,每年再把本金加上收益就好了。 代码: #include<bits/stdc++.h> const int N=1e7+10; const int mod=1e7+9; const int maxn=0x3f3f3f3f; const int minn=0xc0c0c0c0; const int ...

Z7784562的博客 433

9.23华为OD机试真题 新系统 - 世界杯徽章换购 (Java/Py/C/C++/Js/Go)

9.23华为OD机试真题 新系统 - 世界杯徽章换购 (Java/Py/C/C++/Js/Go)

算法大师! 1588

C# NX二次开发-查找连续倒圆角面

可以通过ufun函数 UF_MODL_ask_face_type 和 UF_MODL_ask_face_props 可判断处理选择相应的一组圆角面。在QQ群里有人问怎么通过一个选择一个倒圆角面来自动选中一组倒圆角面。这个是初步思路,如果有更好的思路可回复讨论一下。

fhqiwmc的博客 617

P1853 投资的最大效益(dp)

这里运用题目给的a是1000的倍数,动态规划时除以1000,避免超出内存限制和超时。数组的下标范围会变得非常大,导致内层循环的迭代次数急剧增加。(购买 1 份债券 1 和 2 份债券 2)。每一年结束后,将当前年的最大利息。如果不除以 1000,

Ct314的博客 365

RH850系列芯片深度剖析 1.5-链接(ld)文件解析

基础编译过程分为四个阶段:预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)、链接(Linking)。执行这四个阶段的程序(预处理器、编译器、汇编器、和链接器)一起构成了编译系统。CONSTANTS接下来的内存空间定义部分会使用这些常量来定义内存空间的范围,理论上来说不定义常量也没有影响,直接用魔鬼数字代替,定义常量的主要目的就是方便理解以及方便修改;从示例中可以看出,常量的值可以为16进制或者10十进制,而且10进制支持数量级单位(k级,M级);

本博客专注于嵌入式软件领域技术分享。 1427

洛谷P1853 投资的最大效益题解

今天还是来切洛谷题啦!

小冻梨的博客 946

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

洛谷P1853 投资的最大效益

当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。2.再考虑一维的完全背包,由题可知,每种债卷要花的钱和利息,会TLE,题目中说了买债卷的钱都是1000的倍数,可以将买债卷的费用和拥有的钱都除以1000,可以采取这种方法。对于 100% 的数据,1≤s≤106,2≤n≤40,1≤d≤10,1≤a≤104,且 a 是 1000 的倍数,b 不超过 a 的 10%。第一行为三个正整数 s,n,d,分别表示最初的总资产、年数和债券的种类。

dldltangmen的博客 821

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

洛谷P1853 投资的最大效益 题解

题目背景 约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。 题目描述 例如:有如下两种不同的债券: 投资额\$4000$4000,年利息\$400$400; 投资额\$3000$3000,年利息\$250$250。 初始时,有\$10000$10000...

qq_62350409的博客 757

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

洛谷P1853 投资的最大效益(完全背包)

链接:https://www.luogu.com.cn/problem/P1853 题目背景 约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。 题目描述 例如:有如下两种不同的债券:①投资额4000,年利息4000,年利息400;②投资额3000,年利息3000,年利息25

Mr.RainsdRop的胡思乱想 388

【dp完全背包】洛谷 P1853 投资的最大效益

题目 题目链接 题目背景 约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。 题目描述 例如:有如下两种不同的债券:①投资额4000,年利息400;②投资额300...

weixin_44197056的博客 297

【洛谷】P1853 投资的最大效益*(完全背包)

穿越隧道 往模板上套 #include <iostream> #include <cstring> using namespace std; const int N = 1e7 + 10, M = 20; int f[N]; int v[M],w[M]; int m,n,d; int main(){ scanf("%d%d%d",&m,&n,&d); for(int i = 1; i <= d; i++){ scanf("%d%d",&

qq_45866781的博客 282

Java解 洛谷P1853 投资的最大效益,包含完整的完全背包状态转移方程,通俗易懂

Java解 洛谷P1853 投资的最大效益,包含完整的完全背包状态转移方程,通俗易懂

qq_46237746的博客 526

洛谷 p1853 投资效益 (背包容量变化的完全背包)2021-08-11

题目背景 约翰先生获得了一大笔遗产,他暂时还用不上这一笔钱,他决定进行投资以获得更大的效益。银行工作人员向他提供了多种债券,每一种债券都能在固定的投资后,提供稳定的年利息。当然,每一种债券的投资额是不同的,一般来说,投资越大,收益也越大,而且,每一年还可以根据资金总额的增加,更换收益更大的债券。 题目描述 例如:有如下两种不同的债券:①投资额4000,年利息4000,年利息400;②投资额3000,年利息3000,年利息250。初始时,有10000的总资产,可以投资两份债券①债券,一年获得10000的.

Jacob0824的博客 225

完全背包讲解及例题

本文讲解了完全背包问题的基本概念与代码实现。完全背包是动态规划中的经典问题,允许物品无限选取,采用正序更新策略优化计算。文章提供了C++模版代码,并通过洛谷P1616、P1832等例题展示应用。对于难度较高的题目(如P1853投资效益、P5662纪念品),作者给出了优化思路和解决代码,最后均成功通过测试。适合算法初学者学习完全背包的基本原理和实际应用。

初心如磐,逐梦前行||b站@一个空客迷 1198

2019.7.12 sdfzoier做题统计

lixf_lixf :9 P1981表达式求值 P1076寻宝 P1199三国游戏 P1308统计单词数 P1190接水问题 P1158导弹拦截 P1070道路游戏 P1069细胞分裂 P1058立体图 kevin_M_S 3 acwing 超快速排序 最高的牛 分形之城 wujialin 2 acwing 129火车进站 128编辑器 liuxiny...

weixin_30770495的博客 186

动态规划--背包问题

背包问题是动态规划最经典的问题之一,在这里,我们初步学会如何使用动态规划解决问题绝大部分情况下,动态规划步骤如下:1.状态表示:dpij→dpij→集合描述2.状态计算:划分集合,把当前状态转化为子集状态(注意不重不漏)→\to→进而写出状态转移方程接下来,让我们到题目中理解这两步的含义吧!以上便是背包问题最基础的4类模型,实际上的题目可能会结合上其他算法(状态压缩、贪心、树形DP⋯\cdots⋯又或是进行变式(求方案数,多目标⋯\cdots⋯。

mathematicians的博客 600

2021-07-21

洛谷 P1734 最大约数和 代码: #include<bits/stdc++.h> using namespace std; long long dp[1005],val[1005],w[1005]; int help(int x) { int sum=0; for(int i=1;i<=x-1;i++) if(x%i==0) sum+=i; return sum; } int main() { int s; cin>>s; for(int i=1;i&

lmy_edison的博客 143

【题解】luogu p1853 投资的最大效益

一个简单的背包模型题(我还是没做出来) https://www.luogu.org/problemnew/solution/P1853 #include<bits/stdc++.h> using namespace std; int s, n, d, a[51], b[51], dp[100000000]; int main() { cin >>...

weixin_30882895的博客 195
上一篇: HDOJ 1114 【Piggy-Bank】
下一篇: HDOJ 1059【Dividing】
Masker_43
博客等级 码龄8年 5粉丝 143原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值