这个是一个背包的变形题,很值得仔细体味

大致题意:

这个比普通背包多一个限制:再选每一类物品之前必须要先购买一个篮子来装,篮子有一定的价格,其他就和背包是一样的了

思路:

为了能够体现篮子的价值,我们可以多加一维表示当前买第i个篮子和不买的情况

dp[i][j][0]表示用j个金币且第i个物品篮子没有买的前提下能获得最多的价值

dp[i][j][1]表示用j个金币且第i个物品篮子已经买的前提下能获得最多的价值

那么状态建好了,下面试着进行状态转移

dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j][1]);

dp[i][j][1]的状态转移稍微复杂一点,因为第i类物品有好几个,这个时候我们就要对i类每一个物品进行01选择

设当前物品价格p价值v

dp[i][j][1] = max(dp[i][j][1], dp[i][j-c-p][0]+v, dp[i][j-p][1] + v);

哈哈多么漂亮机智的移到

Description

FJ is going to do some shopping, and before that, he needs some boxes to carry the different kinds of stuff he is going to buy. Each box is assigned to carry some specific kinds of stuff (that is to say, if he is going to buy one
of these stuff, he has to buy the box beforehand). Each kind of stuff has its own value. Now FJ only has an amount of W dollars for shopping, he intends to get the highest value with the money. 
 

Input

The first line will contain two integers, n (the number of boxes 1 <= n <= 50), w (the amount of money FJ has, 1 <= w <= 100000) Then n lines follow. Each line contains the following number pi (the price of the ith box 1<=pi<=1000),
mi (1<=mi<=10 the number goods ith box can carry), and mi pairs of numbers, the price cj (1<=cj<=100), the value vj(1<=vj<=1000000) 
 

Output

For each test case, output the maximum value FJ can get 
 

Sample Input

3 800
300 2 30 50 25 80
600 1 50 130
400 3 40 70 30 40 35 60
 

Sample Output

210
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<stack>
#include<map>
#include<queue>
#include<vector> using namespace std;
const int maxn = 1e5+100;
const int INF = 0x7f7f7f7f;
#define pr(x) cout << #x << " = " << x << " ";
#define prln(x) cout << #x << " = " << x <<endl;
#define ll long long
int max(int a,int b,int c){
return max(max(a,b),c);
}
int dp[maxn][2], p, c, v, num;
int main(){
#ifdef LOCAL
freopen("C:\\Users\\User Soft\\Desktop\\in.txt","r",stdin);
//freopen("C:\\Users\\User Soft\\Desktop\\out.txt","w",stdout);
#endif
int n, m, k;
while(scanf("%d%d", &n, &m)==2){
memset(dp,0,sizeof dp);
for(int i = 1; i <= n; ++i) {
scanf("%d%d", &p, &num);
for(int j = 0; j <=m; ++j){
dp[j][0] = max(dp[j][0], dp[j][1]);
if(j < p) dp[j][1] = -INF;
else dp[j][1] = 0;
}
for(int j = 1; j <= num; ++j) {
scanf("%d%d",&c, &v);
for(int j = m; j >= 0; --j) {
if(j >= p + c)
dp[j][1] = max(dp[j-c-p][0] + v, dp[j-c][1] + v, dp[j][1]);
}
}
}
cout << max(dp[m][1], dp[m][0]) << "\n";
}
return 0;
}

最新文章

  1. JS原型链
  2. 【bzoj4517】 Sdoi2016—排列计数
  3. 用HTML做的简单的个人简历
  4. java实现服务端守护进程来监听客户端通过上传json文件写数据到hbase中
  5. 如何让JQuery报错-遁地龙卷风
  6. windows xp/7命令提示符强制结束指定进程
  7. JSON 基础知识总结
  8. Linux基础: 系统加载过程和运行级别含义
  9. 剑指Offer23 二叉树中和为sum的路径
  10. select2 取值 赋值
  11. 解决Eclipse中编辑xml文件的智能提示问题,最简单的是第二种方法。
  12. 语句(语句分类及if语句)
  13. 开发中经常遇到SVN清理失败的问题:
  14. 学习Karma+Jasmine+istanbul+webpack自动化单元测试
  15. 判断window.open的页面是否已经被关
  16. sqlserver 查询重复数据
  17. 用mysql workbench导出mysql数据库关系图
  18. numpy.squeeze()的用法
  19. 【android】SDK环境变量配置
  20. hiho1613 墨水滴

热门文章

  1. 基于Idea从零搭建一个最简单的vue项目
  2. http响应代码解释
  3. 从0构建webpack开发环境(三) 开发环境以及 webpack-dev-server 的使用
  4. 如何判断元素是否在可视区域内--getBoundingClientRect
  5. 让centos使用ubuntu的make命令补全功能
  6. Spring 事物机制(总结)
  7. Linux 下源码安装ngnix
  8. HTML超链接应用场景
  9. mongodb Access control is not enabled for the database 无访问控制解决方案
  10. bzoj5161 最长上升子序列 状压DP(DP 套 DP) + 打表