解决思路(动态规划)
我们假设 value 表示背包的总价值,k 表示放进去的物品的编号(这里我规定物品编号从1开始)。C 表示当前背包的当前的重量。
所以我们可以用一个共识来表示 value = B(k,C) 。B为一个函数,可以看作 将1到k的物品放入背包并且规定当前背包的容量,就可以得到他们当前最大的价值。
然后我们可以推断出。
包不够大
如果 第k个物品要放进去的时候,当前容量是C。C+K的重量>背包的重量那么:
B(k,C) = B(k-1,C)
包够
如果不大于则表示可以放入。
那么 则有两种情况,一个是放入,一个是不放入
包够大,且可以放入
放入那它的价值 value =B(k,C)=B(k-1,C-Ck) + Vk
注:Ck是K的重量,Vk是K的价值,C为当前背包容量
可能有疑惑的是:为什么要C-Ck,因为这种考虑是像K放入的时候,可能会将之前放入的几个物品或者全部物品排挤出去,但不能保证是否是可以保值的。
包够大,但不放
那么 B(k,C) = B(k-1,C)
放与不放做比较,取最大值
所以在可以放的情况下,B(k,C) = max(B(k-1,C), B(k,C)=B(k-1,C-Ck) + Vk注意事项:
参考代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 101010;
int a[N],b[N],dp[N],v,q,p,k=1;
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=m;++i){
cin>>v>>p>>q;
if(!q){
a[k]=v;
b[k++]=p*v;
}
else {
a[q]+=v;
b[q]+=p*v;
}
}
for(int i=1;i<=k;++i){
for(int j=n;j>=a[i];--j){
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}
}
cout<<dp[n];
return 0;
}
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复