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

大致题意:

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

思路:

为了能够体现篮子的价值,我们可以多加一维表示当前买第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;
}

HDU3449_Consumer的更多相关文章

随机推荐

  1. 小Q的棋盘 (贪心)

    小Q的棋盘 (贪心) 题目 洛谷传送门 做法 显然这是一棵树(这个就不多bb了,树的性质) 很容易发现一个性质,如果一条链走完,我们必须回头再走一次那条链(或一部分)才可以走到更多的点 所以为了减少这 ...

  2. php页面出现空白解决方法

    查询php程序使用内存情况 $size = memory_get_usage(); file_put_contents("d:/data.php", var_export($siz ...

  3. Using text search in Web page with Sikuli

    在網頁中如何使用Sikuli找特定字串呢? 原理: 我們可以使用 組合鍵 ctrl + 來放大網頁的比例,使得sikuli的OCR功能找的更清準 實作: for i in range(4): type ...

  4. 那些年很脑残的bugs

    1.老师给了前端界面,我们用java写后台. 我改了表单form的action属性,让它跳到自己写的servlet上面去.自己在servlet里面对数据库一顿操作猛如虎,然后让servlet跳回原来页 ...

  5. JS中的reduce函数

    海纳百川,有容乃大 定义: reduce()方法接受一个函数作为累加器,数组中的每个值(从左向右)开始缩减,最终计算为一个值.对空数组是不会执行回调函数的. 案例: 计算数组总和: var num = ...

  6. facenet 人脸识别(一)

    前言 已完成TensorFlow Object Detection API环境搭建,具体搭建过程请参照: 安装运行谷歌开源的TensorFlow Object Detection API视频物体识别系 ...

  7. (ACM模板)二元组pair

    #include<iostream> #include<cstdio> #include<utility> using namespace std; typedef ...

  8. bzoj4036 [HAOI2015]按位或 状压DP + MinMax 容斥

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4036 题解 变成 \(2^n-1\) 的意思显然就是每一个数位都出现了. 那么通过 MinMa ...

  9. python tkinter开始

    tkinter是python自带的GUI库,所以用起来会比较简单 运行一个什么都没有的窗口 import tkinter window=tkinter.Tk()#窗口类定义 window.mainlo ...

  10. react-jsx和数组

    JSX: 1.全称:JavaScriptXML, 2.react定义的一种类似于XML的JS扩展语法:XML+JS 3.作用:用来创建react虚拟DOM(元素)对象 var ele=<h1&g ...