传送门

题目大意

给你n个物品,你有一个容量为W的背包,每一个物品都有它的重量和价值,让你从n个中选取若干个,使得总重量不超过背包的上限,而且使得价值最大。

分析

首先我们不难发现由于W很大,所以这并不是一个普通的01背包,但是我们发现由于所有的wi相差很小,所以如果按体积大小分类,所有物品将仅有4类,这样我们就可以枚举美类物品取了多少了,但是这样虽然时间复杂度没问题但空间会炸。于是我们用dpijk表示考虑到了第i个物品,共取了j个,这j个物品的体积和 - w1*j = k,这样我们就可以在满足复杂度的情况下得到总体积了。具体转移见代码。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl
int dp[][][],w[],v[];
int main(){
int n,m,i,j,k;
cin>>n>>m;
for(i=;i<=n;i++)
scanf("%d%d",&w[i],&v[i]);
for(i=;i<=n;i++)
for(j=;j<=i;j++)
for(k=;k<=*i;k++){
dp[i][j][k]=max(dp[i][j][k],dp[i-][j][k]);
if(k>=w[i]-w[])
dp[i][j][k]=max(dp[i][j][k],dp[i-][j-][k-(w[i]-w[])]+v[i]);
}
int ans=;
for(i=;i<=n;i++)
for(j=;j<=i*;j++)
if((long long)i*w[]+j<=(long long)m)
ans=max(ans,dp[n][i][j]);
cout<<ans<<endl;
return ;
}

最新文章

  1. MyBatis入门学习教程-解决字段名与实体类属性名不相同的冲突
  2. svg-filter高斯模糊
  3. 安装windows后重新修复grub2的引导
  4. java对象序列化byte[] and byte[]反序列化对象--转
  5. [CLR via C#]11. 事件
  6. hdu 3717
  7. PHP 正则表达式匹配 preg_match 与 preg_match_all 函数
  8. CodeForces 701C They Are Everywhere
  9. 关于文件上传的ajax交互
  10. 运用socket实现简单的ssh功能
  11. Python内置函数(24)——set
  12. js的一些注意点
  13. 【JSOI2018】潜入行动
  14. python入门学习:8.类
  15. officewebapps 服务器部署问题
  16. UVAL 4728 Squares(旋转卡壳)
  17. eclipse逆向生成hibernate的实体类(注解和配置文件)
  18. Eclipse配置问题
  19. 选择排序之Java实现
  20. from会存在潜在的陷阱

热门文章

  1. CCTextFieldTTF 与 5种常用CCMenuItem
  2. golang实现模拟键盘按键
  3. MySQL安装后默认自带数据库的作用
  4. java 实现拖动文件到窗口功能
  5. YII1.1分页
  6. dockerfile http_php
  7. TreeView 树节点的处理
  8. JSF使用HTML5的custom attribute
  9. Linux应用程序调用其他程序执行
  10. Linux驱动 - 多线程