P2370 yyy2015c01 的 U 盘 背包+二分
Posted pangbi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2370 yyy2015c01 的 U 盘 背包+二分相关的知识,希望对你有一定的参考价值。
题意:给出n个文件,每个文件有大小、价值两个参数
给出一个u盘,u盘有容量参数(存放文件的大小总和不能超过这个容量)
有一个传输通道,通道也有大小参数,传输的文件的大小不能大过这个通道大小
问:给定一个价值大小p,让我们去寻找一个最小的通道大小,
做到在这个大小的情况下,能够装到的价值大于等于此价值p
思路:二分。我们二分对象为通道大小,范围为(0,1e3)不过我在代码中开到了1e4,这没什么影响
但是:要跑出结果来,需要用到01背包,用背包思想将能够装的东西,在有限的空间内装到最大即可
再根据这个结果来决定往左区间跑还是右区间跑即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e3+10; 4 const int inf=0x3f3f3f3f; 5 int dp[maxn]; 6 struct node 7 { 8 int x,y; 9 }G[maxn]; 10 bool cmp(node t1,node t2) 11 { 12 return t1.x<t2.x; 13 } 14 int n,limit,s; 15 int check(int mid) 16 { 17 memset(dp,0,sizeof(dp)); 18 for(int i=1;i<=n;i++){ 19 if(G[i].x<=mid){ 20 for(int j=s;j>=G[i].x;j--){ 21 dp[j]=max(dp[j],dp[j-G[i].x]+G[i].y); 22 } 23 } 24 else break; 25 } 26 if(dp[s]>=limit) return 1; 27 else return 0; 28 } 29 int main() 30 { 31 scanf("%d%d%d",&n,&limit,&s); 32 int sum=0; 33 for(int i=1;i<=n;i++){ 34 scanf("%d%d",&G[i].x,&G[i].y); 35 sum+=G[i].y; 36 } 37 if(limit>sum){ 38 printf("No Solution! "); 39 return 0; 40 } 41 // if(sum<limit){ 42 // printf("No Solution! "); 43 // return 0; 44 // } 45 sort(G+1,G+1+n,cmp); 46 int L=0,R=1e4; 47 int ans=inf; 48 while(L<=R){ 49 int mid=L+R>>1; 50 if(check(mid)){ 51 ans=mid; 52 R=mid-1; 53 } 54 else L=mid+1; 55 } 56 if(ans==inf) printf("No Solution! "); 57 else printf("%d ",ans); 58 return 0; 59 60 }
以上是关于P2370 yyy2015c01 的 U 盘 背包+二分的主要内容,如果未能解决你的问题,请参考以下文章