您的位置:首页 > 其它

HDU 3449 Consumer 依赖背包

2017-11-21 16:45 375 查看
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


最初呢,我是这么想的:根据依赖背包,每一组都可以划分为花费0-v的最大值,相当于每一组v件物品进行分组背包。耿直一发,绝对超时,仅仅是判断我思路是否正确

然后我就枚举了每一种组的每一种状态,因为每一组数量不超过10,所以最多1024种状态,于是就又耿直的状压了一发,TLE。

经过计算,时间复杂度大约1e9。

然后又想了一下,最后的状态不过是有些东西选,有些东西不选,这就是一个整体01背包,但是需要先买一个盒子。然后就过了- - 超坎坷

#include<bits/stdc++.h>
using namespace std;
int dp[55][100800];
int cost[100],val[100];
int main()
{
int n,v;
while(scanf("%d%d",&n,&v)!=EOF)
{

memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
{
int V,t;
scanf("%d%d",&V,&t);
for(int k=v; k>=V; k--)
dp[i][k]=dp[i-1][k-V];
for(int j=0; j<t; j++)
{
scanf("%d%d",&cost[j],&val[j]);
for(int k=v; k>=max(cost[j],V); k--)///k>=max(cost[j],V),保证了每次dp【i】【j】都是在V的范围之内
{
if(k-cost[j]>=V)///保证都是由放入箱子这个状态转移而来
dp[i][k]=max(dp[i][k],dp[i][k-cost[j]]+val[j]);
}

}
for(int j=0; j<=v; j++)///可以选择放,可以选择不放
dp[i][j]=max(dp[i-1][j],dp[i][j]);
}
printf("%d\n",dp
[v]);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: