2639骨头问题2(01背包的第k大值)
来源:互联网 发布:linux系统运维 编辑:程序博客网 时间:2024/05/01 17:42
Problem Description
The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup" competition,you must have seem this title.If you haven't seen it before,it doesn't matter,I will give you a link:
Here is the link:http://acm.hdu.edu.cn/showproblem.php?pid=2602
Today we are not desiring the maximum value of bones,but the K-th maximum value of the bones.NOTICE that,we considerate two ways that get the same value of bones are the same.That means,it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum.
If the total number of different values is less than K,just ouput 0.
Here is the link:http://acm.hdu.edu.cn/showproblem.php?pid=2602
Today we are not desiring the maximum value of bones,but the K-th maximum value of the bones.NOTICE that,we considerate two ways that get the same value of bones are the same.That means,it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum.
If the total number of different values is less than K,just ouput 0.
Input
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, K(N <= 100 , V <= 1000 , K <= 30)representing the number of bones and the volume of his bag and the K we need. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Followed by T cases , each case three lines , the first line contain two integer N , V, K(N <= 100 , V <= 1000 , K <= 30)representing the number of bones and the volume of his bag and the K we need. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Output
One integer per line representing the K-th maximum of the total value (this number will be less than 231).
对01背包理解还是不透彻,看了大神的代码都半天没反应过来。
大神给dp数组加了一个维度,存放最大的k个值。
只有一个物品时候,只有放和不放两个值,存到k数组。这是背包的两个可能的状态,并排序
当有两个物品时候,在第一个放和不放状态上又可以有放和不放。以此类推。所以有了k的循环,每次都把放和不放的状态与原来的几种状态依次相加,得到新的状态
因为dp数组初始化都是0,是有序的,每次放完a,b中间数组都是严格递减的,原因是dp[j][k]一定大于dp[j][k+1],所以无论取dp[j][k]或者dp[j][k-vol[i]]+val[i]都是严格递减
所以排序时候可以用类似归并排序的合并方法。大神把排序的数组最后一个设为负数,就不用管边界问题,非常好的方法。
每次找出前k个最优值,然后存入dp数组。如果不满k个,则后面的是0,对下一次决策没影响,到时候对结果也没影响,因为结果让不满k个输出0,只是排序的时候注意一下去重。上大神代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAXN 105
#define MAXV 1005
int MyMax(int a,int b)
{
return (a>b?a:b);
}
int main()
{
int t,n,v,m;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
int i,j,k;
int val[6],vol[6],dp[11][3];
int a[35],b[35];
scanf("%d%d%d",&n,&v,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&val[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&vol[i]);
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
for(j=v;j>=vol[i];j--)
{
for(k=1;k<=m;k++)
{
a[k]=dp[j-vol[i]][k]+val[i];
b[k]=dp[j][k];
}
int x,y,z;
x=y=z=1;
a[k]=b[k]=-1;
while(z<=m&&(y<=m||x<=m))
{
if(a[x]>b[y])
{
dp[j][z]=a[x++];
}
else
{
dp[j][z]=b[y++];
}
if(dp[j][z]!=dp[j][z-1])
{
z++;
}
}
}
}
printf("%d\n",dp[v][m]);
}
}
return (0);
}
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAXN 105
#define MAXV 1005
int MyMax(int a,int b)
{
return (a>b?a:b);
}
int main()
{
int t,n,v,m;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
int i,j,k;
int val[6],vol[6],dp[11][3];
int a[35],b[35];
scanf("%d%d%d",&n,&v,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&val[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d",&vol[i]);
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
for(j=v;j>=vol[i];j--)
{
for(k=1;k<=m;k++)
{
a[k]=dp[j-vol[i]][k]+val[i];
b[k]=dp[j][k];
}
int x,y,z;
x=y=z=1;
a[k]=b[k]=-1;
while(z<=m&&(y<=m||x<=m))
{
if(a[x]>b[y])
{
dp[j][z]=a[x++];
}
else
{
dp[j][z]=b[y++];
}
if(dp[j][z]!=dp[j][z-1])
{
z++;
}
}
}
}
printf("%d\n",dp[v][m]);
}
}
return (0);
}
0 0
- 2639骨头问题2(01背包的第k大值)
- HDU2693 骨头收藏家II(第k大背包)
- HDU 2639 第K大背包问题
- 背包问题--求第K大值
- hdu2639-01背包(第k大背包问题)
- hdu2639(01背包的第K大)
- hdu2639(第k大值+01背包)
- hdu 2639 Bone Collector II 01背包问题 求第K大最优值。。
- 01背包第k大
- hdu2639(求价值第K大的01背包)
- HDU - 2639 Bone Collector II(第K大01背包)
- hdu 2639 Bone Collector II 第k大01背包
- hdu 2639求背包第K大值
- 01背包第k大价值hdu2639
- HDU 2639 Bone Collector II / 第K大的01背包
- HDU 2639 Bone Collector II 收集骨头II+第k最优值
- 背包问题之 “骨头收藏家”
- hdu2639(01背包变形-第k大背包)
- keil c51使用技巧及实战
- linux基础学习小记
- Coroutines in C
- 将整数转化成字符串
- android中parceable接口的使用
- 2639骨头问题2(01背包的第k大值)
- 自己写perl 模块
- BloomFilter——大规模数据处理利器
- 获取像素颜色(cocos2dx3.0)
- hdu5147----Sequence II
- 在学习java框架时,用myeclipse工具,写xml文件时,想让提示 配置如下:
- JMeter从入门到精通
- WEB编程入门经典 HTML/CSS 第一章2
- 在Linux上实现一个可用的stateless双向静态NAT模块