HDU3449_Consumer

来源:互联网 发布:windows update在哪里 编辑:程序博客网 时间:2024/06/05 05:08

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

大致题意:

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

思路:

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

0 0
原创粉丝点击