我的算法修炼之路--7—— 手撕多重背包、贪心+差分,DFS,从数学建模到路径DP


💗博主介绍:计算机专业的一枚大学生 来自重庆 @燃于AC之乐✌专注于C++技术栈,算法,竞赛领域,技术学习和项目实战✌💗
💗根据博主的学习进度更新(可能不及时)
💗后续更新主要内容:C语言,数据结构,C++、linux(系统编程和网络编程)、MySQL、Redis、QT、Python、Git、爬虫、数据可视化、小程序、AI大模型接入,C++实战项目与学习分享。
👇🏻 精彩专栏 推荐订阅👇🏻
点击进入🌌作者专栏🌌:
算法画解
C++
🌟算法相关题目点击即可进入实操🌟
感兴趣的可以先收藏起来,请多多支持,还有大家有相关问题都可以给我留言咨询,希望希望共同交流心得,一起进步,你我陪伴,学习路上不孤单!

文章目录

  • 前言
  • 题目清单
    • 1.Tallest Cow S (最高的奶牛)
    • 2.英雄联盟
    • 3.小A的糖果
    • 4.Cow Picnic S(奶牛野餐)
    • 5.税收与补贴问题
    • 6. 传纸条

前言

这些题目摘录于洛谷,好题,典型的题,考察各类算法运用,可用于蓝桥杯及各类算法比赛备战,算法题目练习,提高算法能力,补充知识,提升思维。
锻炼解题思路,从学会算法模板后,会分析,用到具体的题目上。
对应题目点链接即可做。

本期涉及算法:动态规划–多重背包,贪心 + 差分,贪心算法,dfs暴搜,数学(解决应用题),动态规划–路径dp(方格取数问题)

题目清单

1.Tallest Cow S (最高的奶牛)

题目:P2879 [USACO07JAN] Tallest Cow S


解法:贪心 + 差分

题目要求右端点大于等于左端点,且中间更小,满足要求的最大安排,我们开始可以贪心地构造,开始让所有的奶牛一样最高(因为最高值这里给出了),左可以等于右,中间的小于两边的端点,让中间的只少1,那么就是每给一段区间,让中间的区间全部-1,想到用差分数组进行处理。最后的值:起始最高的高度 + 前缀和处理后的差分数组对应值(处理后的变化量)

特殊处理:1.这道题会有重复数据,不用再处理,因为此时以满足要求,要最高,每处理一次高度会减小,要用set<pair<int, int>> mp; 来存,帮助去重,同时可以用mp.count({a, b})标记当前数据是否存过,结束,优化; 2.a > b, 要swap(a, b)

代码:

#include<iostream>#include<set>usingnamespacestd;constintN=1e4+10;intn,id,h,r;intf[N];//差分数组intmain(){cin>>n>>id>>h>>r;set<pair<int,int>>mp;//会有重复的修改区间,去重while(r--){inta,b;cin>>a>>b;if(a>b)swap(a,b);//[a + 1, b - 1]if(mp.count({a,b}))continue;//重复的不再进行修改f[a+1]--;f[b]++;mp.insert({a,b});}for(inti=1;i<=n;i++){f[i]+=f[i-1];cout<<h+f[i]<<endl;//开始默认都为最大高度h,然后按题目输入条件修改, h + 变化量}return0;}

2.英雄联盟

题目:P5365 [SNOI2017] 英雄联盟

解法:动态规划–多重背包

从前往后挑选皮肤(物品),搭配的展示方案数 >= M的最小花费,且物品数有限制,可以想到多重背包问题。

1.状态表示:

这道题的精彩之处,可以有两种状态表示,其中一种不行。

这里有两种状态表示都能解决问题:

a. f[i] [j] 表示从前i个英雄中挑选,总⽅案数不低于j时,此时的最小花费;

b. f[i] [j] 表示从前i个英雄中挑选,总花费为j时,此时的最大方案数。

如果选第⼀种,时间和空间都会超,因为第⼆维的最大值是1e17 。因此,我们选择第⼆种状态

表示。在打表结束之后,从前往后扫描最后一行,从f[n] [1] 开始找出第⼀个方案数超过m的花费为最小,即为结果。

2.状态转移方程:

根据第i个英雄选择皮肤数量分类讨论,假设选了p个皮肤,其中0 <= p <=k[i],并且p * c[i] <= j, 此时的最大方案数为f[i - 1] [j - p * c[i]] * p。也就是前i - 1个英雄中挑选,总价值为**j - p * c[i]**时最大方案数再乘上此时的选择数量。

因为要的是最大值,所以状态转移⽅程就是所有合法k情况下的最⼤值。

3.初始化:

f[0] [0] = 1 ,因为后续方案数是累乘,所以这⾥初始化为 1 就能保证后续
填表是正确的。

代码:

#include<iostream>usingnamespacestd;typedeflonglongLL;constintN=300,M=1e6+10;LL n,m;LL cnt[N],v[N];LL f[M];LL sum;//最大花费intmain(){cin>>n>>m;for(inti=1;i<=n;i++)cin>>cnt[i];for(inti=1;i<=n;i++){cin>>v[i];sum+=v[i]*cnt[i];}f[0]=1;for(inti=1;i<=n;i++){for(intj=sum;j>=0;j--){for(intk=0;k<=cnt[i]&&k*v[i]<=j;k++){f[j]=max(f[j],f[j-k*v[i]]*k);}}}for(intj=1;j<=sum;j++){//从花费最小的开始找第一个满足要求的if(f[j]>m){cout<<j<<endl;break;}}return0;}

3.小A的糖果

题目:P3817 小A的糖果

解法:贪心

从前往后考虑每个盒子糖果数,如果第i个盒子,a[i] + a[i - 1] > x, 拿走糖果。

怎么拿?

贪心1:想到拿尽量少且满足要求,即为d = a[i] + a[i - 1] -x。拿前面一个会对与后面的数量和产生影响;

贪心2:从第二个开始,把开始前面一个看成0个处理,因为如果只有三个 2 2 2,要求不超过3,拿掉中间2一个即可。 从头开始看前一个与当前这个i的和可以合理更新。为了让后⾯相邻元素累加尽可能小,应该从 i 位置拿⾛ d 的糖果,此时 a[i] =a[i] - d ,化简完之后为a[i] = x - a[i - 1]

代码:

#include<iostream>usingnamespacestd;typedeflonglongLL;constintN=1e5+10;LL n,x;LL a[N];intmain(){cin>>n>>x;LL sum=0;for(inti=1;i<=n;i++){cin>>a[i];LL d=a[i]+a[i-1]-x;if(d>0){sum+=d;a[i]=x-a[i-1];}}cout<<sum<<endl;return0;}

4.Cow Picnic S(奶牛野餐)

题目:P2853 [USACO06DEC] Cow Picnic S

解法:dfs/bfs暴搜

要想每个奶牛都能到达牧场以(k个奶牛)每个奶牛的位置为起点做一次dfs/bfs,标记可以到达的点,哪些结点被标记了k次,即为所求结果。

代码:

#include<iostream>#include<cstring>#include<vector>usingnamespacestd;constintN=1010;intk,n,m;inta[N];//k头奶牛的编号vector<int>edges[N];intcnt[N];boolst[N];voiddfs(intu){st[u]=true;cnt[u]++;for(intv:edges[u]){if(!st[v])dfs(v);}}intmain(){cin>>k>>n>>m;for(inti=1;i<=k;i++)cin>>a[i];for(inti=1;i<=m;i++){intx,y;cin>>x>>y;edges[x].push_back(y);}for(inti=1;i<=k;i++){memset(st,0,sizeofst);//重置更新为0dfs(a[i]);}intret=0;for(inti=1;i<=n;i++){if(cnt[i]==k)ret++;}cout<<ret<<endl;return0;}

5.税收与补贴问题

题目:P1023 [NOIP 2000 普及组] 税收与补贴问题

解法:数学

设政府干预x元。

可列式子:

d = (130 - 120) / (30 - 28) = 5。

(28 - 28 + x)* 130

(29 - 28 + x)* 125,

(30 - 28 + x)* 120

(31 - 28 + x)110*

d = 15。

(32 - 28 + x) * 95

(33 - 28 + x) * 80

……

​ (38 - 28 + x ) * 5

(31 - 28 + x) * 110 > =(28 - 28 + x)* 130, (29 - 28 + x)* 125, (30 - 28 + x)* 120

分别化为 x <= p1, x <= p2, x <= p3.要想全部都满足,则:

x <= (p1, p2, p3)min

(31 - 28 + x) * 110 >= (32 - 28 + x) * 95, (33 - 28 + x) * 80……(38 - 28 + x ) * 5

分别化为 x >= p4, x >= p5, x >= p6……要想全部都满足,则:

x >= (p3, p4, p5 ……)max

政府规定价格aim,成本:a,销量:c[i],表示售价为i时的对应销量。

(aim - a + x) * c[aim] >= (i - a + x) * c[i],

(aim - a) * c[aim] + x * c[aim] >= (i - a) + c[i] + x * c[i]

x * (c[aim] _ c[i]) >= (i - a) * c[i] - (aim - a) * c[aim]

1.c[aim] > c[i] , x >= ((i - a) * c[i] - (aim - a) * c[aim]) / (c[aim] _ c[i])

2.c[aim] < c[i] , x <= ((i - a) * c[i] - (aim - a) * c[aim]) / (c[aim] _ c[i])

细节处理:

left < x < right。

1.left > right,x无解;

2.right < 0, left < 0,x取绝对值较小,值较大的,就是舍(向下取整),用floor(right);

3.right > 0, left > 0,x取绝对值较小,值较小的,就是入(向上取整),用ceil(left);

4.left < 0, right >0,x取绝对值较小,取0

代码:

#include<iostream>#include<cmath>usingnamespacestd;constintN=1e5+10;intaim,a;intc[N];//售价为 i 时,销量为 c[i]intmain(){cin>>aim;intx,y;cin>>x>>y;a=x;c[x]=y;intprev=x;//存前一个的定价while(cin>>x>>y,x!=-1&&y!=-1){intd=(c[prev]-y)/(x-prev);for(inti=prev+1,j=c[prev]-d;i<=x;i++,j-=d){c[i]=j;}prev=x;//还原}intd;cin>>d;for(inti=prev+1,j=c[prev]-d;j>=0;i++,j-=d){c[i]=j;prev=i;}doubleleft=-1e9,right=1e9;for(inti=a;i<=prev;i++){doublex=1.0*((i-a)*c[i]-(aim-a)*c[aim])/(c[aim]-c[i]);if(c[aim]>c[i])left=max(left,x);elseif(c[aim]<c[i])right=min(right,x);}if(left>right)cout<<"NO SOLUTION"<<endl;elseif(right<0)cout<<(int)floor(right)<<endl;elseif(right>0)cout<<(int)ceil(left)<<endl;elsecout<<0<<endl;return0;}

6. 传纸条

题目:P1006 [NOIP 2008 提高组] 传纸条

解法:动态规划–路径类dp

类似方格取数,但与方格取数的不同点在于处理相遇点的策略,这里不能有相遇点。

1.状态表示:

f[st] [i1] [i2] 表示:第⼀条路在 [i1 ,st− i1 ] ,第⼆条路在 [i2 , st − i2] 时,两者的路径最⼤和。

那我们的最终结果就是 f[n + m] [m] [m]。

2.状态转移方程:

第⼀条路可以从上[i1 - 1, st - i1]或者左[i1, st - i1 - 1]走到[i1, st - i1]位置;第⼆条路可以从上[i2 - 1, st - i2] 或者左[i2, st - i2 -1]走到[i2, st - i2] 位置。排列组合⼀下⼀共种情况,分别是:

1.上 + 上,此时的最⼤和为:f[st - 1] [i1 - 1] [i2 - 1]

上 + 左,此时的最⼤和为:f[st - 1] [i1 -1] [i2];

左 + 上,此时的最⼤和为:f[st - 1] [i1] [i2 - 1] ;

左 + 左,此时的最⼤和为:f[st - 1] [i1] [i2] ;

取上面四种情况的最大值,然后再加上a[i1] [j1] 和 a[i2] [j2]。

但是要注意,如果两个路径当前在同⼀位置时,直接continue,因为两条路不能走在相同的位

置。不过,如果是最后⼀个格子的话,还是要计算的。

3.初始化:算的是路径和, 0 不会影响最终结果,直接填表。

4.填表顺序:先从小到大循环横纵坐标之和,然后依次从小到大循环两者的横坐标。

代码:

#include<iostream>usingnamespacestd;constintN=55;intm,n;inta[N][N];intf[N+N][N][N];intmain(){cin>>m>>n;for(inti=1;i<=m;i++)for(intj=1;j<=n;j++)cin>>a[i][j];for(ints=2;s<=n+m;s++){for(inti1=1;i1<=m;i1++){for(inti2=1;i2<=m;i2++){if(i1==i2&&s!=n+m)continue;intj1=s-i1,j2=s-i2;if(j1<1||j1>n||j2<1||j2>n)continue;f[s][i1][i2]=max(f[s][i1][i2],f[s-1][i1-1][i2-1]);f[s][i1][i2]=max(f[s][i1][i2],f[s-1][i1-1][i2]);f[s][i1][i2]=max(f[s][i1][i2],f[s-1][i1][i2-1]);f[s][i1][i2]=max(f[s][i1][i2],f[s-1][i1][i2]);f[s][i1][i2]+=a[i1][j1]+a[i2][j2];}}}cout<<f[n+m][m][m]<<endl;return0;}

加油!志同道合的人会看到同一片风景。
看到这里请点个赞关注,如果觉得有用就收藏一下吧。后续还会持续更新的。 创作不易,还请多多支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1174836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VBench-2.0: Advancing Video Generation Benchmark Suite for Intrinsic Faithfulness

一、 核心问题&#xff1a;从“看起来真”到“本质上真” https://arxiv.org/pdf/2503.21755 当前视频生成模型&#xff08;如 Sora, Kling&#xff09;在 “表层保真度” 上已取得惊人进步&#xff1a; 画面美观&#xff1a;单帧图像质量高。 运动平滑&#xff1a;帧间过渡…

计及调度经济性的光热电站储热容量配置方法Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

2026 年 1 月权威 GEO 培训公司 TOP5

2026年1月权威GEO培训公司TOP5一、引言在当今数字化营销的大环境下&#xff0c;GEO优化的重要性日益凸显。企业都希望通过有效的GEO优化来提升在生成式引擎中的可见性&#xff0c;从而获取更多的流量和转化。然而&#xff0c;面对市场上众多的GEO培训机构&#xff0c;企业如何选…

基于混合整数规划的微网储能电池容量规划Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

GESP认证C++编程真题解析 | 202506 五级

​欢迎大家订阅我的专栏:算法题解:C++与Python实现! 本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战! 专栏特色 1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的…

2026 年 1 月零基础 GEO 培训权威 TOP5

2026年1月零基础GEO培训权威TOP5 一、引言 在当今数字化营销的大环境下&#xff0c;GEO优化成为企业提升竞争力的关键领域。对于零基础想要涉足这一领域的个人和企业来说&#xff0c;选择一家权威的GEO培训机构至关重要。目前市场上有多家机构可供选择&#xff0c;以下是一些…

c语言:2026.1.4

1.数组的练习题 (1)删除指定数 先输入10个数字,存在数组中,输入一个整数n,删除等于n的数字,剩余在最前面; 后面的依次覆盖前面,删除一个,只看前九个(数组的有效元素个数-1); 外循环,如果进行了删除操作,i不…

name is simple

but many Chinese parents really love their children, although their names sound like the most unimportant people in English. even Hitler(6) also will have a lovely parent in China.

本科毕业论文降AI率攻略:从70%降到5%的经验分享 - 还在做实验的师兄

本科毕业论文AI率太高会影响答辩。我的经验是用嘎嘎降AI处理,70%的AI率可以降到5%以下。手动改效率太低,直接用工具省时省力。本科毕业论文降AI率攻略:从70%降到5%的经验分享TL;DR:本科毕业论文AI率太高会影响答辩…

开题报告AI率太高怎么办?这几款工具亲测有效 - 还在做实验的师兄

开题报告结构化程度高,AI率普遍在50-70%,容易被检测系统判定为AI生成。推荐用嘎嘎降AI(4.8元/千字,降到5%以下)或比话降AI(8元/千字,效果更极致)处理。开题报告AI率太高怎么办?这几款工具亲测有效TL;DR:开题…

八大排序之:冒泡排序、快速排序和堆排序 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2026年垂直领域GEO服务商先行者综合盘点 - 品牌2025

“推荐一家做工业AI质检的北京公司?”“有哪些适合中小企业的CRM系统?”当用户的搜索行为从输入关键词转变为直接向AI提问,一场静默却深刻的营销革命已然发生。 DeepSeek、豆包、Kimi、腾讯元宝、文心一言等生成式A…

线段树的区间(加、乘)修改、区间询问

线段树的区间(加、乘)修改、区间询问线段树的区间(加、乘)修改、区间询问学习是一个持续的过程,每一小步都是进步。 ———— 我也不知道是谁说的1. 分析问题:修改、询问痛点:直接暴力修改区间每个元素,时间复杂度…

2026年医学论文降AI率工具推荐,专业术语不被误改 - 还在做实验的师兄

医学论文专业术语多,降AI时最担心药名、疾病名被误改。推荐嘎嘎降AI(4.8元/千字,术语保留好)和比话降AI(8元/千字,效果极致)。处理完重点检查专业术语即可。2026年医学论文降AI率工具推荐,专业术语不被误改TL;…

MySQL_分组统计

使用group by字句对列进行分组使用having字句对分别组后的结果进行过滤#演示group by having的使用 #部门表 CREATE TABLE dept( deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, dname VARCHAR(20) NOT NULL DEFAULT "", loc VARCHAR(13) NOT NULL DEFAULT…

基于非合作博弈的风-光-氢微电网容量优化配置Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

MySQL_字符串函数

-- 演示字符串相关函数的使用 &#xff0c; 使用emp表来演示 -- CHARSET(str) 返回字串字符集 SELECT CHARSET(ename) FROM emp; -- CONCAT (string2 [,... ]) 连接字串, 将多个列拼接成一列 SELECT CONCAT(ename, 工作是 , job) FROM emp;-- INSTR (string ,substring ) 返…

吐血推荐!9款AI论文工具测评,本科生写论文必备

吐血推荐&#xff01;9款AI论文工具测评&#xff0c;本科生写论文必备 2026年AI论文工具测评&#xff1a;为什么你需要这份指南&#xff1f; 随着人工智能技术的不断进步&#xff0c;AI论文工具逐渐成为本科生撰写学术论文的重要助手。然而&#xff0c;面对市场上种类繁多、功能…

基于自适应遗传算法的分布式电源优化配置Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

批量发送请求后立即返回线程的处理结果(不阻塞)

基于Spring Boot的CompletableFuture与Consumer批量处理方案 方案概述: 批量请求处理:用户发送多条数据请求,并发处理每条数据线程池执行:使用自定义线程池处理具体业务逻辑 异步结果获取:通过CompletableFuture获…