题面:
https://www.luogu.org/problemnew/show/P3462
https://www.lydsy.com/JudgeOnline/problem.php?id=1110
https://szkopul.edu.pl/problemset/problem/y7tXjqVq0gPZjc8kPrscs2CJ/site/?key=statement
先打了个贪心。直接所有容器从大到小排序,按这个顺序处理容器,每个容器每次装能够装进且最大的砝码。用multiset维护。
WA了(貌似洛谷还骗到40分?)
然后想了想改了一下。先二分答案,对于每个二分出的答案x显然最好方案是取最小的x个砝码。然后就当做只有这些砝码,用前面的贪心判是否有解。
错误记录:没有对砝码按重量排序...
A掉了?(log^2而且常数大,因此bzojA不掉,其他两个地方可以A)
1 #pragma GCC optimize("Ofast") 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #include<set> 7 using namespace std; 8 #define fi first 9 #define se second 10 #define mp make_pair 11 #define pb push_back 12 typedef long long ll; 13 typedef unsigned long long ull; 14 typedef pair<int,int> pii; 15 int n,m; 16 int a[200010],b[200010]; 17 multiset<int> s; 18 bool judge(int x) 19 { 20 s.clear(); 21 int i,t;multiset<int>::iterator i1; 22 for(i=1;i<=x;++i) 23 s.insert(b[i]); 24 for(i=n;i>=1;--i) 25 { 26 t=a[i]; 27 while(!s.empty()&&((i1=s.upper_bound(t))!=s.begin())) 28 { 29 --i1; 30 t-=*i1; 31 s.erase(i1); 32 } 33 } 34 return s.empty(); 35 } 36 int main() 37 { 38 int i; 39 scanf("%d%d",&n,&m); 40 for(i=1;i<=n;++i) 41 scanf("%d",&a[i]); 42 sort(a+1,a+n+1); 43 for(i=1;i<=m;++i) 44 scanf("%d",&b[i]); 45 sort(b+1,b+m+1); 46 int l=0,r=m,mid; 47 while(l!=r) 48 { 49 mid=l+((r-l)>>1); 50 if(judge(mid+1)) l=mid+1; 51 else r=mid; 52 } 53 printf("%d",l); 54 return 0; 55 }