[洛谷]P2370 yyy2015c01的U盘 (#二分答案 -1.1)(#动态规划 -背包 -1.11)

题目背景

在2020年的某一天,我们的yyy2015c01买了个高端U盘。

题目描述

你找yyy2015c01借到了这个高端的U盘,拷贝一些重要资料,但是你发现这个U盘有一些问题:

1、这个U盘的传输接口很小,只能传输大小不超过L的文件

2、这个U盘容量很小,一共只能装不超过S的文件

但是你要备份的资料却有很多,你只能备份其中的一部分。

为了选择要备份哪些文件,你给所有文件设置了一个价值Vi,你希望备份的文件总价值不小于 p

但是很快你发现这是不可能的,因为yyy2015c01的传输接口太小了,你只有花钱买一个更大的接口(更大的接口意味着可以传输更大的文件,但是购买它会花费更多的钱)

注意:你的文件不能被分割(你只能把一个文件整个的传输进去,并储存在U盘中),

你放在U盘中文件的总大小不能超过U盘容量

现在问题来了:你想知道,在满足U盘中文件价值之和 不小于 p时,最小需要多大的接口

输入输出格式

输入格式:

第1行,三个正整数 n, p, S 分别表示 文件总数, 希望最小价值p,硬盘大小

接下来n行

每行两个正整数 Wi, Vi 表示 第i个文件的大小,和价值

输出格式:

一共1行,输出一个正整数表示最小需要的接口大小

如果无解输出 “No Solution!” 不含引号

输入输出样例

输入样例#1

3 3 5
2 2
1 2
3 2

输出样例#1

2

输入样例#2

2 3 505
1 2
500 1

输出样例#2

500

输入样例#3

3 3 2
2 2
1 2
3 2

输出样例#3

No Solution!

输入样例#4

4 5 6
5 1
5 2
5 3
1 1

输出样例#4

No Solution!

说明

数据范围:

1 ≤ n, Wi, S ≤ 1 000

1 ≤ Vi ≤ 1 000 000

1 ≤ p ≤ 1 000 000 000

数据较小,请勿乱搞。

样例解释1: (买一个大小为2接口,把物品1、2放进U盘)

样例解释2:(买一个大小为500的接口)

样例解释3:(本来可以买大小为2的接口,可是U盘容量放不下足够的文件)

如果数据出现疏漏,请联系出题人@a710128

向本题主人公yyy2015c01同学致敬

 


思路

先来bb两句本题的接口是什么:

比如一个文件大小是4,那你至少要准备一个4大小的接口。小于4的文件都可以使用这个借口,但是如果文件大小是5,就不能用4接口了,必须买一个5接口的。

然后,本题可以用二分来枚举最小的接口。根据上面对于接口的解释,我们可以r=s,l=0,然后背包来验证价值能否大于最小价值。

#include 
#include 
#include 
using namespace std;
int n,m,s,maxn(-1);
int dp[1001],v[1001],w[1001];
bool bag01(int cnt)//然后背包来验证价值能否大于最小价值
{
	memset(dp,0,sizeof(dp));//清除缓存 
	register int i,j;
	for(i=1;i<=n;i++)
	{
		if(w[i]>cnt)//cnt是当前的mid,也就是目前的接口大小 
		{//如果这个文件的大小大于接口的大小 
			continue;//不能装 
		}
		else for(j=s;j>=w[i];j--)
		{
			dp[j]=max(dp[j],dp[j-w[i]]+v[i]);//裸的01背包,dp[i]大小为i时价值最大 
		}
	}
	if(dp[s]>n>>m>>s;
	for(i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];//读入大小、价值 
	}
	l=0,r=s;//解释过借口是什么意思了,那么区间上限就是磁盘的大小 
	while(l<=r)//二分来枚举最小的接口,结束条件为l>r 
	{
		mid=(l+r)>>1;//显然第一步先找区间中点 
		if(bag01(mid))//bag是返回mid是否可行, 
		{
			maxn=mid;//mid可行,此时记录maxn=mid,mid是目前最优解 
			r=mid-1;//缩小查找范围,r=mid-1,寻找有没有更小的解 
		}//之所以这样做是因为本题也间接提到了最大的最小值 
		else//mid不是最优解,就往大区间找,因为我们希望越小越好,但是目前mid是最小的,且此方案行不通,那就往大区间再找 
		{
			l=mid+1;//找右区间某一个比当前mid大的值 
		}
	}
	if(maxn==-1)
	{
		cout<<"No Solution!"<

 

你可能感兴趣的:(洛谷原创,二分答案,动态规划----背包dp,动态规划,洛谷刷题题解)