P1510 精卫填海

P1510 精卫填海
二分答案
二分背包容量,判断能否满足v。
判断的话就跑01背包就好了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<set>
 8 #include<map>
 9 #include<stack>
10 #include<cstring>
11 #define inf 2147483647
12 #define For(i,a,b) for(register int i=a;i<=b;i++)
13 #define p(a) putchar(a)
14 #define g() getchar()
15 //by war
16 //2017.10.28
17 using namespace std;
18 int f[10010];
19 int v,n,c;
20 int l,r,mid;
21 int tov;
22 int tow;
23 struct stone
24 {
25     int v;
26     int w;
27 }a[10010];
28 void in(int &x)
29 {
30     int y=1;
31     char c=g();x=0;
32     while(c<'0'||c>'9')
33     {
34     if(c=='-')
35     y=-1;
36     c=g();
37     }
38     while(c<='9'&&c>='0')x=x*10+c-'0',c=g();
39     x*=y;
40 }
41 void o(int x)
42 {
43     if(x<0)
44     {
45         p('-');
46         x=-x;
47     }
48     if(x>9)o(x/10);
49     p(x%10+'0');
50 }
51 
52 bool pd(int ans)
53 {
54     For(i,1,ans)
55     f[i]=0;
56     For(i,1,n)
57       for(int j=ans;j>=a[i].w;j--)
58         f[j]=max(f[j],f[j-a[i].w]+a[i].v);
59     if(f[ans]>=v)
60     return true;
61     return false;
62 }
63 
64 int main()
65 {
66     in(v),in(n),in(c);
67     For(i,1,n)
68     {
69         in(a[i].v),in(a[i].w);
70         tov+=a[i].v;
71     }
72     if(tov<v)
73     {
74         puts("Impossible");
75         exit(0);
76     }
77     l=1,r=c;
78     while(l<r)
79     {
80         mid=(l+r)>>1;
81         if(pd(mid))
82         r=mid;
83         else
84         l=mid+1;
85     }
86     if(!pd(l))
87     {
88         puts("Impossible");
89         exit(0);
90     }
91     o(c-l);
92      return 0;
93 }

 

posted @ 2017-10-28 17:56  WeiAR  阅读(252)  评论(0编辑  收藏  举报