P1757 分组背包
题目描述:
解题思路:
依题意得,同组内的元素会互相冲突,也就是说同一组只能选一个,也就是说在组内做01背包。
我们先来看看伪代码:
for 所有的组k
for v=V..0
for 所有的i属于组k
f[v]=max{f[v],f[v-w[i]]+c[i]}
第一重循环比较好理解,就是一组一组下去的做01背包。但是for v=V..0
必须放在for 所有的i属于组k
的外面,这是为了保证在当前容量中,每一个同组的物品只会选到一个。
如:
当枚举到
f
v
f_v
fv 时,
f
v
=
m
a
x
(
f
v
,
f
v
−
w
i
+
v
i
)
f_v=max(f_v\ ,\ f_{v-w_i}+v_i)
fv=max(fv , fv−wi+vi),显然,
f
v
−
w
i
f_{v-w_i}
fv−wi 是选到上一组的时候的最优解,不包括选取当前组内物品的情况,不会影响每一组只选一个的特性。
CODE:
#include <iostream>
#include <cstring>
using namespace std;
int V,n,t;
struct Gar
{
int v[5000],w[5000],len;
} a[200];
long long f[100100]={0};
int main()
{
cin>>V>>n;
for(int i=1;i<=n;i++)
{
int b,c,d;
cin>>b>>c>>d;
t=max(t,d); //最大的组数就是组的总数
a[d].w[a[d].len+1]=b; //将物品分组方便选择
a[d].v[a[d].len+1]=c;
a[d].len++;
}
for(int i=1;i<=t;i++)
{
for(int j=V;j>=0;j--)
{
for(int k=1;k<=a[i].len;k++)
{
if(j<a[i].w[k]) continue; //如果当前容量不能放下当前物品,则跳过
f[j]=max(f[j],f[j-a[i].w[k]]+a[i].v[k]);
}
}
}
cout<<f[V];
return 0;
}
再给一道练习巩固:
TENSHI在经历了无数次学科竞赛的失败以后,得到了一个真理:做一题就要对一题!但是要完全正确地做对一题是要花很多时间(包括调试时间),而竞赛的时间有限。所以开始做题之前最好先认真审题,估计一下每一题如果要完全正确地做出来所需要的时间,然后选择一些有把握的题目先做。 当然,如果做完了预先选择的题目之后还有时间,但是这些时间又不足以完全解决一道题目,应该把其他的题目用贪心之类的算法随便做做,争取“骗”一点分数。
任 务根据每一题解题时间的估计值,确定一种做题方案(即哪些题目认真做,哪些题目“骗”分,哪些不做),使能在限定的时间内获得最高的得分,
Input
第一行有两个正整数N和T,表示题目的总数以及竞赛的时限(单位秒)。以下的N行,每行4个正整数W1i 、T1i 、W2i 、T2i ,分别表示第i题:完全正确做出来的得分,完全正确做出来所花费的时间(单位秒),“骗”来的分数,“骗”分所花费的时间(单位秒)。
其中,3 ≤ N ≤ 30,2 ≤ T ≤ 1080000,1 ≤ W1i 、W2i ≤ 30000,1 ≤ T1i 、T2i ≤ T。
Output
所能得到的最高分值
Sample Input
样例1
4 10800
18 3600 3 1800
22 4000 12 3000
28 6000 0 3000
32 8000 24 6000
样例2
3 7200
50 5400 10 900
50 7200 10 900
50 5400 10 900
Sample Output
样例1
50
样例2
70
Source
elba
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!