【解题报告】分组背包(YBT 1272)
**终于从数据结构的魔圈中走出来啦!!!,今天我终于要写一篇关于 动态规划的题目啦,哈哈哈! **
没看过题目的请戳这里☞
分组背包
先不说什么,直接上代码(代码中有变量解释):
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
struct sd{//结构体
int weight ,value;//重量,价值
}subject;//物品特性
bool judger[202];//判断函数,后面会讲
int M[202];//背包常用数组
vector<sd> group[15];//这里指的是所分的组数
int main()
{
int contain,count,team;//背包重量,物品数量,组数
scanf("%d%d%d",&contain,&count,&team);
int number;//组号
for(int i=1;i<=count;++i)
{
scanf("%d%d%d",&subject.weight,&subject.value,&number);
group[number].push_back(subject);//把同样的组号的物品放在一起!
}
int limit=0;
for(int i=1;i<=team;++i)
{
for(int j=limit;j>=0;--j)
{
for(int k=group[i].size()-1;k>=0;--k)
{
if((j==0||M[j]!=0)&&j+group[i][k].weight<=contain)
{
if(!judger[j]&&M[j+group[i][k].weight]<M[j]+group[i][k].value)
{
M[j+group[i][k].weight]=M[j]+group[i][k].value;
judger[j+group[i][k].weight]=true;
}
if(j+group[i][k].weight>limit)
limit=j+group[i][k].weight;
}
}
}
memset(judger,false,sizeof(judger));
}
int ans=-1;
for(int i=0;i<=contain;++i)
{
if(ans<M[i])
ans=M[i];
}
printf("%d",ans);
return 0;
}
其实认真学过01背包的同学会发现这两个代码其实是非常相似的
下面来对比一波
- 01包代码和分组包代码都是用到了几个for循环,而分组包只是比01包多了一个for循环,用来循环组内的数据(见打了标记的那个for循环)
- 分组包所申请的变量只比01包多了一个judger(变量)
- 然后就没有什么明显区别啦!
下面来一波01包的代码:
#include<cstdio>
#include<cstring>
using namespace std;
int bag[305];
int m,n;
int main()
{
scanf("%d%d",&m,&n);
int a,b;
int limit=0;
for(int i=1;i<=n;++i)
{
scanf("%d%d",&a,&b);
for(int j=limit;j>=0;--j)
{
if(bag[j]!=0||(j==0))
{
if(bag[j+a]<bag[j]+b&&j+a<=m)
{
bag[j+a]=bag[j]+b;
}
if(limit<j+a)
limit=j+a;
}
}
}
int ans=-1;
for(int i=0;i<=m;++i)
{
if(bag[i]>ans)
ans=bag[i];
}
printf("%d",ans);
return 0;
}
judger数组
这里就是分组背包的精髓,judger变量是用来记录当前组内可以扔到背包中的当前点是否已经被组内的其他物品扔到了!如果没有,那就把这个物品扔进去,把扔过他以后到达的那个点的judger记为true(即下一次组内物品往里面背包中扔的时候,不能往刚才扔到的那个点上面扔)(因为题目上说,两个同组的物品不能碰在一起,否则会出事情!嘿嘿嘿!!!),所以说,每次当遍历完一个组的时候,我们就需要把judger数组memset一下,以便于用于下一个数组。
P.s:好好看代码并理解加粗的字,相信你可以想通这个问题!!!
更多背包问题详解请见
背包, 背包
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微服务架构学习与思考:微服务拆分的原则
· 记一次 .NET某云HIS系统 CPU爆高分析
· 如果单表数据量大,只能考虑分库分表吗?
· 一文彻底搞懂 MCP:AI 大模型的标准化工具箱
· 电商平台中订单未支付过期如何实现自动关单?
· Cursor:一个让程序员“失业”的AI代码搭子
· .NET 阻止Windows关机以及阻止失败的一些原因
· 博客园2025新款「AI繁忙」系列T恤上架
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(6)
· Avalonia跨平台实战(二),Avalonia相比WPF的便利合集(一)