Vijos1313 金明的预算方案
2015-09-22 21:50
260 查看
题目大意:给定物品数与总钱数,物品分为主件与附件,想选附件必须选主件,求最大能得到多少给定价值。
思路:绝对是有依赖的背包问题,可将其转化为01背包问题。对于每一个物品集合,取不选、只选主件、多选一个附件、多选两个附件的最大值即可。要注意的一点是,要预处理将属于同一个集合的物品(即主件及其附件)归到一起。
代码如下:
思路:绝对是有依赖的背包问题,可将其转化为01背包问题。对于每一个物品集合,取不选、只选主件、多选一个附件、多选两个附件的最大值即可。要注意的一点是,要预处理将属于同一个集合的物品(即主件及其附件)归到一起。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> using namespace std; const int maxm=65; const int maxv=32005; struct node { int v,p; node(int v=0,int p=0):v(v),p(p){} }; int n,m,tot=0; int f[maxv],po[maxm]; node sub[maxm][5]; map<int,int> has; void init() { scanf("%d%d",&n,&m); memset(f,0,sizeof(f)); memset(po,0,sizeof(po)); for (int i=1;i<=m;++i) { int v,p,q; scanf("%d%d%d",&v,&p,&q); if (q==0) { tot++; has[i]=tot; sub[tot][0]=node(v,p); } else { po[has[q]]++; sub[has[q]][po[has[q]]]=node(v,p); } } } void dp() { int i,j,totv,totvp; for (i=1;i<=tot;++i) for (j=n;j>=0;--j) { if (j-sub[i][0].v>=0) { f[j]=max(f[j],f[j-sub[i][0].v]+sub[i][0].v*sub[i][0].p); } else continue; totv=sub[i][0].v; totvp=sub[i][0].v*sub[i][0].p; for (int a=1;a<=po[i];++a) { totv+=sub[i][a].v; totvp+=sub[i][a].v*sub[i][a].p; if (j-sub[i][0].v-sub[i][a].v>=0) f[j]=max(f[j],f[j-sub[i][0].v-sub[i][a].v]+sub[i][0].v*sub[i][0].p+sub[i][a].v*sub[i][a].p); } if (j-totv>=0) f[j]=max(f[j],f[j-totv]+totvp); } printf("%d\n",f ); } int main() { init(); dp(); return 0; }
相关文章推荐
- Android Studio 插件--postfix
- SQlite常用语句
- 移动IM开发学习<4>
- 第4周-点是否在圆内
- 网络3层相关的几个问题
- Android基于位置的服务开发,百度地图的使用
- espcms列表页ajax无限加载
- ios textfied文本框设置代码
- [转载]Matlab fmincon函数用法
- spark core源码分析17 RDD相关API
- 轻松搞定面试中的二叉树题目
- 关于js中的闭包
- 解决键盘老是不消失实现delegate委托实例化过程
- 深度学习Matlab工具箱代码注释——cnnapplygrads.m
- Html 嵌入 swf
- 数独设计(1)
- hadoop2.7.1单机版安装部署
- hdu 1028 整数划分 (母函数)
- 安卓:handler向子线程发送消息
- SDUT 顺序表应用5:有序顺序表归并(插入排序)