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

大致题意:

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

思路:

为了能够体现篮子的价值,我们可以多加一维表示当前买第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. python学习第六天--匿名函数、过滤、映射

    匿名函数 lambda表达式 过滤器 filter(判断函数,可迭代对象) 会根据提供的函数对指定序列做过滤 映射 map(判断函数,可迭代对象) 会根据提供的函数对指定序列做映射

  2. 任务21 :了解ASP.NET Core 依赖注入,看这篇就够了

    DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET  Core的DI实现以及对实例 ...

  3. 循环冗余校验(CRC)

    冗余码 CRC和海明校验类似,也是有效信息(k位)+校验信息(r位),需要满足N=k+r≤2r-1 生成多项式G(X) 定义:收发双方约定的一个(r+1)位二进制数,发送方利用G(X)对信息多项式做模 ...

  4. 【刷题】java 常见的几种运行时异常RuntimeException

    常见的几种罗列如下: -NullPointerException - 空指针引用异常 ClassCastException - 类型强制转换异常. IllegalArgumentException - ...

  5. k3 cloud成本调整单提示期末余额不存在调整单分录的维度,请先出库核算确认是否存在核算维度的数据

    成本调整单提示期末余额不存在调整单分录的维度,请先出库核算确认是否存在核算维度的数据,如下图所示: 解决办法:先做出库核算,然后做成本调整单,再做出库核算(出库成本核算)

  6. 奇异值分解基础(SVD)

    最近要了解一下Incremental PCA的一些知识,然后看到一篇论文里面讲到了SVD(奇异值分解),奈何自己以前没有把机器学习的课好好上,现在很多东西还是要补回来.所以,我就想了解一些SVD的基础 ...

  7. Java笔试题-List l = new List()

    前言: 最近遇到的一道很基础的题,有时候大家可能离开了编译器就不行了. import java.util.List; /** * * @author catchegg * create date: 2 ...

  8. ahocorasick使用

    一.作用 字符串匹配,比如现在有个大的列表,客户输入一句话,如何根据客户输入的一句话,从大列表中匹配出字符串交集 具体请详细查阅 二.示例 比如我们有一个wordlist列表,长度很长,包含43430 ...

  9. Sass函数:数字函数-ceil()函数

    ceil() 函数将一个数转换成最接近于自己的整数,会将一个大于自身的任何小数转换成大于本身 1 的整数.也就是只做入,不做舍的计算: >> ceil(2.0) 2 >> ce ...

  10. ElasticSearch(java) 创建索引

    搜索]ElasticSearch Java Api(一) -创建索引 标签: elasticsearchapijavaes 2016-06-19 23:25 33925人阅读 评论(30) 收藏 举报 ...