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!\n");
39         return 0;
40     }
41 //    if(sum<limit){
42 //        printf("No Solution!\n");
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!\n");
57     else printf("%d\n",ans);
58     return 0;
59 
60 }
View Code

 

posted @ 2020-04-14 19:58  古比  阅读(153)  评论(0编辑  收藏  举报