From easthong

背包的第k优解

 
     
     
  描述 Description  
  DD 和好朋友们要去爬山啦!他们一共有 K 个人,每个人都会背一个包。这些包的容量是相同的,都是 V。可以装进背包里的一共有 N 种物品,每种物品都有给定的体积和价值。

在 DD 看来,合理的背包安排方案是这样的:

1. 每个人背包里装的物品的总体积恰等于包的容量。
  2. 每个包里的每种物品最多只有一件,但两个不同的包中可以存在相同的物品。
  3. 任意两个人,他们包里的物品清单不能完全相同。

在满足以上要求的前提下,所有包里的所有物品的总价值最大是多少呢?

     
     
  输入格式 Input Format  
  第一行有三个整数:K、V、N。

第二行开始的 N 行,每行有两个整数,分别代表这件物品的体积和价值。

     
     
  输出格式 Output Format  
  只需输出一个整数,即在满足以上要求的前提下所有物品的总价值的最大值。
     
     
  样例输入 Sample Input  
   
     
     
  样例输出 Sample Output  
   
     
     
  时间限制 Time Limitation  
  1s
     
     
  注释 Hint  
  数据范围

总人数 K<=50。

每个背包的容量 V<=5000。

物品种类数 N<=200。

其它正整数都不超过 5000。

输入数据保证存在满足要求的方案。

     
     
  来源 Source  
  dd 2007 dp 模拟赛
 
慢慢啃
f[j][u]表示空间为j时的第u优解;

 
性质:加了一个u循环操作的01背包,i表示加入第i个物品则循环顺序从外到里为i->j->u(就是把原本f[j]=max(f[j-w[i]]+v[i],f[j])的位置变成u的循环操作而已);
 
初始化: 
f[j][u]=负无穷(u循环操作前要判定f[j-w[i]][1]>=0),f[0][1]=0;
 
u的循环操作:
1.已知f[j]=max(f[j-w[i]]+v[i],f[j]),即f[j]有两种取值方案;
用两个数组st1[u]和st2[u]分别储存f[j-w[i]][u]+v[i]和f[j][u];
2.因为f[j][u]一定优于f[j][u+1],所以st1[u]一定优于st1[u+1],st2[u]同理,所以只需要比较st1和st2中的元素就可以得到当前可以取到的最优值;
所以f[i][u]等于st1[tail1]和st2[tail2]中较大的;
3.因为不能有一样的方案,所以st1[tail1],st2[tail2]中较大的数被f[i][u]取值后,对应的tail++(tail在u循环开始前定义为0或者1);
 
 
随着j的增大,方案数是树状增多的,但是前u个最优方案一定是在这棵树的某一个分支上,这个分支的父节点一定是某一个阶段的最优方案,就像分封制一样,离最后的最优方案血缘关系越远优秀程度越差,嗯我是这么理解的.....
 
因为动态规划每一个阶段的方案只和前一个阶段有关,所以可以在输入数据后直接j循环,不需要v[i]w[i]之类存储每一个状态的数组...
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int k,v,n;
long long f[][]={};
long long st1[]={};
long long st2[]={};
int main(){
cin>>k>>v>>n;
for(int i=;i<v;i++){
for(int j=;j<=k;j++){
f[i][j]=-;
}
}
f[][]=;
for(int i=;i<=n;i++){
int a,b;
cin>>a>>b;
for(int j=v;j>=a;j--){
if(f[j-a][]>=){
int p1=,p2=;
for(int u=;u<=k;u++){
st1[u]=f[j-a][u]+b;
st2[u]=f[j][u];
if(st2[p2]>=st1[p1]) f[j][u]=st2[p2++];
else f[j][u]=st1[p1++];
}
}
}
}
long long ans=;
for(int i=;i<=k;i++){
ans+=f[v][i];
}
cout<<ans<<endl;
return ;
}
 

背包的第k优解[动态规划]的更多相关文章

  1. 关于01背包求第k优解

    引用:http://szy961124.blog.163.com/blog/static/132346674201092775320970/ 求次优解.第K优解 对于求次优解.第K优解类的问题,如果相 ...

  2. Bone Collector II---hdu2639(01背包求第k优解)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639求01背包的第k大解.合并两个有序序列 选取物品i,或不选.最终的结果,是我们能在O(1)的时间内 ...

  3. hdu2639(背包求第k优解)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639 题意:给出一行价值,一行体积,让你在v体积的范围内找出第k大的值 分析:dp[i][j][k]表 ...

  4. 01背包(第k优解)

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  5. hdu 2639 Bone Collector II (01背包,求第k优解)

    这题和典型的01背包求最优解不同,是要求第k优解,所以,最直观的想法就是在01背包的基础上再增加一维表示第k大时的价值.具体思路见下面的参考链接,说的很详细 参考连接:http://laiba2004 ...

  6. HDU 2639 (01背包第k优解)

    /* 01背包第k优解问题 f[i][j][k] 前i个物品体积为j的第k优解 对于每次的ij状态 记下之前的两种状态 i-1 j-w[i] (选i) i-1 j (不选i) 分别k个 然后归并排序并 ...

  7. 01背包之求第K优解——Bone Collector II

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 题目大意是,往背包里赛骨头,求第K优解,在普通01背包的基础上,增加一维空间,那么F[i,v,k]可以理解 ...

  8. (01背包 第k优解) Bone Collector II(hdu 2639)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639       Problem Description The title of this problem i ...

  9. 背包【p1858】 多人背包(次优解 or 第k优解)

    题目描述--->p1858 多人背包 分析: 很明显,这题是背包问题的一种变形. 求解 次优解or第k优解. 表示刚开始有点懵,看题解也看不太懂. 又中途去补看了一下背包九讲 然后感觉有些理解, ...

随机推荐

  1. 【BZOJ】1355 [Baltic2009]Radio Transmission

    [算法]KMP [题解]KMP中n-next[n]得到最小循环节的性质. 考虑一个循环串(最后一个循环节可能残缺),它最长的[后缀=前缀]一定是以第二个循环节为起始位置的后缀. 正着考虑的话假设后缀T ...

  2. 爬虫实战--利用Scrapy爬取知乎用户信息

    思路: 主要逻辑图:

  3. npm的常用命令

    npm install <name>安装nodejs的依赖包 例如npm install express 就会默认安装express的最新版本,也可以通过在后面加版本号的方式安装指定版本, ...

  4. C++类型转换 -- 由其他类型转换到自定义类型

    由其他类型转换到自定义类型 由其他类型(如int,double)向自定义类的转换是由构造函数来实现,只有当类的定义和实现中提供了合适的构造函数,转换才能通过. /******************* ...

  5. linux编程之main()函数启动过程【转】

    转自:http://blog.csdn.net/gary_ygl/article/details/8506007 1 最简单的程序  1)编辑helloworld程序,$vim helloworld. ...

  6. Ubuntu连接多台Ubuntu server的问题

    如果您用的是虚拟机上安装的几个Ubuntu server进行IP配置 要注意以下几点: <1>虚拟机上安装完成Ubuntu server 默认的网络连接方式是NAT ,应该改成桥接网卡 ( ...

  7. u-boot启动第二阶段以及界面命令分析

    u-boot第一阶段完成了一些平台相关的硬件的配置,第一阶段所做的事情也是为第二阶段的准备,我们知道在第一阶段最后时搭建好C运行环境,之后调用了start_armboot(),那么很显然第二阶段从st ...

  8. Linux下通过源码编译安装程序(configure/make/make install的作用,然后在/etc/profile文件里修改PATH环境变量)

    一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 库文件:就是通常我们见到的lib目录下的文件 配置文件:这个不必多说,都知道 帮助文档:通常是我们在 ...

  9. javscript练习(三)

    编写一个函数,计算两个数字的和差积商 function calculator(num1,num2,sign){          switch(sign){                   cas ...

  10. normalize.css阅读笔记

    最近在被各种浏览器的CSS兼容折磨,所以看了看normalize的源代码来了解一些常见的浏览器间不一致的CSS渲染问题…… 源代码在这里 text-size-adjust 用法参见Apple的文档和M ...