题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3449

题目大意:

fj打算去买一些东西,在那之前,他需要一些盒子去装他打算要买的不同的物品。每一个盒子有特定要装的东西(就是说如果他要买这些东西里的一个,他不得不先买一个盒子)。每一种物品都有自己的价值,现在FJ只有W元去购物,他打算用这些钱买价值最高的东西。

思路:

这是有依赖的背包,每件物品买之前必须买特定的盒子

背包九讲:

所以先对每一个箱子进行01背包,保存可以凑出的所有的花费和该花费的最大价值,这是一组中的所有状态,且只能取一个或者不取,背包转化成分组背包,然后就可以做了。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int, int> Pair ;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ;
int T, n, m, cases;
struct node
{
int price;
int num;
int price_sum;
int cost[], value[];
int dp[];
};
node a[];
int dp[maxn];
int main()
{
while(cin >> n >> m)
{
memset(dp, , sizeof(dp));
memset(a, , sizeof(a));
for(int i = ; i < n; i++)
{
scanf("%d%d", &a[i].price, &a[i].num);
a[i].price_sum = ;
for(int j = ; j < a[i].num; j++)
{
scanf("%d%d", &a[i].cost[j], &a[i].value[j]);
a[i].price_sum += a[i].cost[j];
}
}
for(int i = ; i < n; i++)//对,每个箱子预处理出所有可凑出的花费和该花费的最大价值
{
memset(a[i].dp, -, sizeof(a[i].dp));
a[i].dp[] = ;
for(int j = ; j < a[i].num; j++)
{
for(int k = a[i].price_sum; k >= a[i].cost[j]; k--)
if(a[i].dp[k - a[i].cost[j]] >= )a[i].dp[k] = max(a[i].dp[k], a[i].dp[k - a[i].cost[j]] + a[i].value[j]);
}/*
for(int j = 0; j <= a[i].price_sum; j++)
cout<<a[i].dp[j]<<" ";
cout<<endl;*/
}
for(int i = ; i < n; i++)//枚举每一个的箱子
{
vector<Pair>d;
for(int j = ; j <= a[i].price_sum; j++)//将该箱子的所有状态存下来
{
if(a[i].dp[j] > )
d.push_back(Pair(j + a[i].price, a[i].dp[j]));
}
for(int v = m; v >= ; v--)//枚举花费
{
for(int j = ; j < d.size(); j++)//枚举改组的状态
if(v >= d[j].first)
dp[v] = max(dp[v], dp[v - d[j].first] + d[j].second);
}
}
cout<<dp[m]<<endl;
}
return ;
}

还有一种写法,在dp的时候把预处理和状态转化合并起来,时间复杂度降低了一点

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int, int> Pair ;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ;
int T, n, m, cases;
int a[];
int dp[][];
struct node
{
int v, w;
};
vector<node>G[];
int main()
{
while(cin >> n >> m)
{
memset(dp, , sizeof(dp));
for(int i = ; i <= n; i++)G[i].clear();
int tot, x, y;
for(int i = ; i <= n; i++)
{
scanf("%d%d", &a[i], &tot);
for(int j = ; j < tot; j++)
{
scanf("%d%d", &x, &y);
G[i].push_back(node{x, y});
}
} for(int i = ; i <= n; i++)//枚举每种箱子
{
for(int j = ; j < a[i]; j++)dp[i][j] = -;
for(int j = a[i]; j <= m; j++)dp[i][j] = dp[i - ][j - a[i]];//这里是确保先购买购物车 for(int j = ; j < G[i].size(); j++)//在购物车内进行01背包
{
for(int k = m; k >= G[i][j].v; k--)
{
if(dp[i][k - G[i][j].v] != -)
dp[i][k] = max(dp[i][k], dp[i][k - G[i][j].v] + G[i][j].w);
}
}
for(int j = ; j <= m; j++)dp[i][j] = max(dp[i - ][j], dp[i][j]);//和之前的值比较
}
cout<<dp[n][m]<<endl;
}
return ;
}

hdu-3449 Consumer---有依赖性质的背包的更多相关文章

  1. hdu 3449 Consumer (依赖01背包)

    题目: 链接:pid=3449">点击打开链接 题意: 思路: dp[i][j]表示前i个箱子装j钱的材料可以得到的最大价值. 代码: #include<iostream> ...

  2. HDU 1561&HDU 3449 一类简单依赖背包问题

    HDU 1561.这道是树形DP了,所谓依赖背包,就是选A前必须选B,这样的问题.1561很明显是这样的题了.把0点当成ROOT就好,然后选子节点前必须先选根,所以初始化数组每一行为该根点的值.由于多 ...

  3. HDU 3449 Consumer (背包问题之有依赖背包)

    题目链接 Problem Description FJ is going to do some shopping, and before that, he needs some boxes to ca ...

  4. HDU 3449 Consumer

    这是一道依赖背包问题.背包问题通常的解法都是由0/1背包拓展过来的,这道也不例外.我最初想到的做法是,由于有依赖关系,先对附件做个DP,得到1-w的附件背包结果f[i]表示i花费得到的最大收益,然后把 ...

  5. HDU 2159 FATE(二维费用背包)

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  6. HDU 1712 ACboy needs your help(包背包)

    HDU 1712 ACboy needs your help(包背包) pid=1712">http://acm.hdu.edu.cn/showproblem.php? pid=171 ...

  7. 【MVVM Dev】多个具有依赖性质的ComboBox对数据的过滤

    一.前言 在界面编程中,我们常常会遇到具有依赖性质的ComboBox框,比如最常见的: 省/直辖市 => 地级市/区 => 区/街道 今天就说一下在WPF的MVVM模式中如何实现该功能 二 ...

  8. HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包)

    HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包) 题意分析 裸的完全背包问题 代码总览 #include <iostream> #include <cstdio> ...

  9. 洛谷 P1064 金明的预算方案【有依赖的分组背包】

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱 ...

随机推荐

  1. spring AOP正则表达式的几个问题

    基于包名的正则表达式,是根据抽象父类的包名过滤,还是实现类的包名过滤, 还是抽象父类实现的接口的包名过滤? org.springframework.aop.aspectj.AspectJExpress ...

  2. Web 2.0 浏览器端可靠性测试第2部分(如何发现和分析 Web 2.0 浏览器端的内存泄漏)

    介绍浏览器端的可靠性测试 在上一编文章中我们介绍了浏览器端可靠性测试的概念.测试方法.以及常用的测试和分析工具.我们知道,浏览器端可靠性测试,就是以浏览器为测试平台,通过模拟用户在真实场景下的页面操作 ...

  3. XAMPP 更换其它路径

    打开安装路径: xampp\apache\conf\httpd.conf DocumentRoot “C:/xampp/htdocs” <Directory “C:/xampp/htdocs”& ...

  4. 不要在Application中缓存数据

    在你的App中的很多地方都需要使用到数据信息,它可能是一个session token,一次费时计算的结果等等,通常为了避免Activity之间传递数据的开销,会将这些数据通过持久化来存储.   有人建 ...

  5. 用LaTeX画树形结构

    用LaTeX画树形结构,比如:文件目录树形图,程序中函数调用关系图等. 找到的一个不错的资源: http://www.texample.net/tikz/examples/feature/trees/ ...

  6. [inner] bug

    这样正确 command: ["sh", "-c", "mysql -h${DC_DB_HOST} -uroot -p${MYSQL_ROOT_PAS ...

  7. 11073 最热门的K个搜索串

    11073 最热门的K个搜索串时间限制:350MS 内存限制:65535K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC;VCDescription大家都非常喜欢而习惯用baidu ...

  8. PlayMaker Play Sound 和 Audio Play

    这两个 Action 都可以播放声音 *Play Sound:只要把声音拖进去就可以: *Audio Play:要求游戏对象要有Audio Source组件.

  9. 多级菜单 menu

    jquery menu: http://jqueryui.com/menu/ Kendo UI Demos http://demos.telerik.com/kendo-ui/web/menu/ind ...

  10. Android Studio中导入v4,v7和recyclerview-v7包的方法

    概述 Android Studio中新建工程中会默认导入v7的包,即在gradle中默认配置了com.android.support:appcompat-v7:x.x.x的依赖.但是不会默认为我们配置 ...