1. 程式人生 > >洛谷 P3462 [POI2007]ODW-Weights

洛谷 P3462 [POI2007]ODW-Weights

題面:

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 }
View Code