这是一道依赖背包问题。
背包问题通常的解法都是由0/1背包拓展过来的,这道也不例外。
我最初想到的做法是,由于有依赖关系,先对附件做个DP,得到1-w的附件背包结果f[i]表示i花费得到的最大收益,然后把每个f[i]看成花费为i+c[i],收益为f[i]的物品依次做0/1背包。
显然,问题是物品数目过多,复杂度为w*w,无法承受。
同时,此问题的主件收益为0这一点也需要细加考虑,由于主件收益为0,其实际上对每个附件方案的影响只有花费+c[i],这样考虑下来我们只需要对附件进行DP,然后附加上+c[i]的影响即可。

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<cstdlib>
using namespace std;
#define ll long long
#define up(i,j,k) for(int i=(j);i<=(k);i++)
#define cmin(a,b) a=min(a,b)
#define cmax(a,b) a=max(a,b)
#define pii pair<int,int>
const int maxn=,inf=1e9,mod=;
int read(){
int ch=getchar(),x=,f=;
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')x=(x<<)+(x<<)+ch-'',ch=getchar();
return f*x;
}
int n,w;
int f[maxn],g[maxn],p[],m[];
int c[],v[];
int main(){
freopen("chad.in","r",stdin);
freopen("chad.out","w",stdout);
while(scanf("%d%d",&n,&w)!=EOF){
memset(f,,sizeof(f));
memset(g,,sizeof(g));
up(i,,n){
scanf("%d%d",&p[i],&m[i]);
up(j,,m[i]){
scanf("%d%d",&c[j],&v[j]);
for(int k=w;k>=c[j];k--)
g[k]=max(g[k-c[j]]+v[j],g[k]);
}
up(j,p[i],w)f[j]=max(f[j],g[j-p[i]]);
memcpy(g,f,sizeof(f));
} printf("%d\n",f[w]);
}
return ;
}

事实上,第一种方法也是可行的,只不过,需要先对g数组进行一个(小优化)。

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<cstdlib>
using namespace std;
#define ll long long
#define up(i,j,k) for(int i=(j);i<=(k);i++)
#define cmin(a,b) a=min(a,b)
#define cmax(a,b) a=max(a,b)
#define pii pair<int,int>
const int maxn=,inf=1e9,mod=;
int read(){
int ch=getchar(),x=,f=;
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')x=(x<<)+(x<<)+ch-'',ch=getchar();
return f*x;
}
int n,w;
int f[maxn],g[maxn],p[],m[];
int c[],v[],head,q[maxn];
int main(){
freopen("chad.in","r",stdin);
freopen("chad.out","w",stdout);
while(scanf("%d%d",&n,&w)!=EOF){
memset(f,,sizeof(f));
memset(g,,sizeof(g));
up(i,,n){
scanf("%d%d",&p[i],&m[i]);
memset(g,,sizeof(g));
up(j,,m[i])scanf("%d%d",&c[j],&v[j]);
up(j,,m[i])for(int k=w;k>=c[j];k--)
g[k]=max(g[k-c[j]]+v[j],g[k]);
head=;
for(int j=;j<=w;j++)
if(!j||g[j]!=g[j-])q[++head]=j;
for(int j=w;j>=p[i];j--){
for(int k=;q[k]+p[i]<=j&&k<=head;k++)
f[j]=max(f[j],f[j-p[i]-q[k]]+g[q[k]]);
}
}
printf("%d\n",f[w]);
}
return ;
}

HDU 3449 Consumer的更多相关文章

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

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

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

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

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

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

  4. HDu 3449 (有依赖的01背包) Consumer

    题意: 有n件物品,对应有不同的价格和价值,这是典型的01背包.但现在有了一个限制,要买物品先买能装这件物品的特定的盒子,盒子的价值为0 代码理解得还不是太好,感觉这是一个“二重”的01背包.首先假设 ...

  5. hdu 3449 有依赖性的01背包

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3449  Consumer Description FJ is going to do so ...

  6. hdu 3449

    有依赖的背包,转化成01背包来做: #include<iostream> #include<cstdio> #include<cstring> #include&l ...

  7. hdu 3449 (有依赖的01背包)

    依赖背包 事实上,这是一种树形DP,其特点是每个父节点都需要对它的各个儿子的属性进行一次DP以求得自己的相关属性. fj打算去买一些东西,在那之前,他需要一些盒子去装他打算要买的不同的物品.每一个盒子 ...

  8. HDU 3449 依赖背包

    这道题虽然水水的,但是还是成功地给我增加了10多个WA. 最开始拿着题,一看,依赖背包嘛~直接DFS树形DP嗨起来,甚至连内存都没有算一下,3MLE: 然后又仔细看了一下题,没有必要用树形背包来做嘛, ...

  9. 【DP_背包专题】 背包九讲

    这段时间看了<背包九讲>,在HUST VJUDGE上找到了一个题单,挑选了其中16道题集中做了下,选题全部是HDU上的题,大多是简单题.目前做了点小总结,大概提了下每道题的思路重点部分,希 ...

随机推荐

  1. Spring MVC配置静态资源和资源包教程

    1- 介绍 这篇教程文章是基于: Spring 4 MVC 2- 创建一个项目 File/New/Other.. 输入: Group ID: com.yiibai Artifact ID: Sprin ...

  2. Eclipse 重启选项

    重启 Eclipse 重启选项允许用户重启 Eclipse. 我们可以通过点击 File 菜单选择 Restart 菜单项来重启 Eclipse. 在安装插件后,用户一般都会被提醒要重启 Eclips ...

  3. Hive查询错误:FAILED: RuntimeException Cannot make directory: hdfs://

    解决方法,关闭hadoop安全模式: hadoop dfsadmin -safemode leave

  4. Linux网络编程(一)基础

    一.数据存储顺序:大端和小端 大端模式: 地址的增长顺序与值的增长顺序相反         小段模式: 地址的增长顺序与值的增长顺序同样 为什么会有大小端模式之分呢?这是由于在计算机系统中,我们是以字 ...

  5. OpenCV学习笔记四:ImgProc模块

    一,简介 这个模块包含一系列的常用图像处理算法. 二,分析 此模块包含的文件如下图: 其导出算法包括如下: /*********************** Background statistics ...

  6. wxPython安装使用

    https://wiki.wxpython.org/How to install wxPython pip install -U wxPython 验证版本 D:\python>python P ...

  7. [HAOI2012]Road

    2750: [HAOI2012]Road Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 728  Solved: 349[Submit][Status ...

  8. 【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演

    [BZOJ3994][SDOI2015]约数个数和 Description  设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组 ...

  9. 解决windows server 2003不识别移动硬盘

    解决windows server2003不显示移动硬盘的问题: 1.进入命令提示符环境(也就是DOS) 2.进入DISKPART程序 3.输入AUTOMOUNT ENABLE指令 4.输入OK 下次U ...

  10. 内置函数:sorted 用法

    内置函数——sorted  对list.dict进行排序,Python提供了两个方法 对给定的List L进行排序,方法1: 用List的成员函数sort进行排序,在本地进行排序,不返回副本方法2: ...