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 }