3 条题解
-
0
/* 数量太多,朴素的做k次01背包就复杂度过高 因为做了很多重复性工作,有些选取是等效的 这里采用二进制分组的方式拆分优化该问题 例如6个物品拆成1 2 3 3组,那么该3个数字 的任意组合就可以凑出1到6的所有数字了(不重复选取)。 所以转化为01背包问题 对于每一个物品个数: 一直拆成2的次方个,如果不够了,就单独在列一组即可 回到这道题,最多有2000个,2的10次方就是1024,最多估计有个10组 所以v,w这里定义大小是10000. */ #include<bits/stdc++.h> using namespace std; int N,V,v[10005],w[10005],f[2005],v1,w1,m1,cnt; int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>N>>V; for(int i=1;i<=N;i++) { cin>>v1>>w1>>m1;//体积,价值,个数 int c=1;//从1开始 while(m1-c>0)//能拆就一直拆 { m1-=c; v[++cnt]=c*v1; w[cnt]=c*w1; c*=2;//每拆一次去乘以2 } v[++cnt]=m1*v1;//拆不动了剩下的单独拿一组 w[cnt]=m1*w1; } for(int i=1;i<=cnt;i++)//一共cnt个物品做01背包 { for(int j=V;j>=v[i];j--) { f[j]=max(f[j],f[j-v[i]]+w[i]); } } cout<<f[V]; return 0; }
-
-3
写题解请注意 鼓励大家写题解,但注意题解格式。
题解一定要有思路解析或代码注释,能否让别人理解你的思路
也是你的能力的检验,不要只放无意义的代码给大家复制,那就失去了做题的初心。
给代码两端加上这个会舒服一些
```cpp
你的代码
```
</span>
这个点在键盘的左上角tab上面那个键,注意切换输入法
#include<iostream> using namespace std; int main() { int n; cin>>n;//这是一个注释 return 0; }
请注意严禁抄袭题解,写题解不要只放代码,需加上你的思路或代码注释。
抄袭题解一经发现直接取消成绩。
题解被删除的可能
- 代码不符合格式规范
- 没有思路讲解或者没有注释,
- 无意义的题解
大家携手共同维护一个良好的编程环境,如果一经发现,多次作乱。可能会被管理员拉黑,请注意,一旦拉黑即失去登陆资格。
- 1
信息
- ID
- 885
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 53
- 已通过
- 19
- 上传者