Atcoder ABC144 Gluttony(贪心+二分)
Problem Statement
Takahashi will take part in an eating contest. Teams of NN members will compete in this contest, and Takahashi's team consists of NN players numbered 11 through NN from youngest to oldest. The consumption coefficient of Member ii is AiAi .
In the contest, NN foods numbered 11 through NN will be presented, and the difficulty of Food ii is FiFi . The details of the contest are as follows:
- A team should assign one member to each food, and should not assign the same member to multiple foods.
- It will take x×yx×y seconds for a member to finish the food, where xx is the consumption coefficient of the member and yy is the difficulty of the dish.
- The score of a team is the longest time it takes for an individual member to finish the food.
Before the contest, Takahashi's team decided to do some training. In one set of training, a member can reduce his/her consumption coefficient by 11 , as long as it does not go below 00 . However, for financial reasons, the NN members can do at most KK sets of training in total.
What is the minimum possible score of the team, achieved by choosing the amounts of members' training and allocating the dishes optimally?
Constraints
- All values in input are integers.
- 1≤N≤2×1051≤N≤2×105
- 0≤K≤10180≤K≤1018
- 1≤Ai≤106 (1≤i≤N)1≤Ai≤106 (1≤i≤N)
- 1≤Fi≤106 (1≤i≤N)1≤Fi≤106 (1≤i≤N)
Input
Input is given from Standard Input in the following format:
NN KK A1A1 A2A2 ...... ANAN F1F1 F2F2 ...... FNFN
Output
Print the minimum possible score of the team.
Sample Input 1
3 5 4 2 1 2 3 1
Sample Output 1
2
They can achieve the score of 22 , as follows:
- Member 11 does 44 sets of training and eats Food 22 in (4−4)×3=0(4−4)×3=0 seconds.
- Member 22 does 11 set of training and eats Food 33 in (2−1)×1=1(2−1)×1=1 second.
- Member 33 does 00 sets of training and eats Food 11 in (1−0)×2=2(1−0)×2=2 seconds.
They cannot achieve a score of less than 22 , so the answer is 22 .
Sample Input 2
3 8 4 2 1 2 3 1
Sample Output 2
0
They can choose not to do exactly KK sets of training.
Sample Input 3
11 14 3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2
Sample Output 3
12
大意是给两个序列a1~an,f1~fn,可以任意地将ai与fj一一对应,同时有一个数k,可将a序列的某些数减小(减小的值累计不超过k,ai不能为负数)求如何操作后ai*fj的最大值最小。
最大值最小问题,很裸的二分。当时做的时候总想成是对ai*fj求和,只贪心就不太可以...二分的话由于ai*fi有单调性,所以直接二分答案,left=0,right=1e12。最关键的是check函数。首先用到贪心的思想,肯定是拿尽可能小的ai和尽可能大的fj配对,要不然大的和大的配最大值肯定会更大,所以先把a序列由小到大sort,f序列由大到小sort,check的时候检查如果当前ak*fk>mid,则减去那一部分,同时累加cnt变量(向上取整),最后看cnt是否大于k即可。
#include<iostream> #include<cmath> #include<algorithm> using namespace std; int n; long long int k; long long a[200005],f[200005]; bool cmp(int a,int b) { return a>b; } int check(long long mid) { long long cnt=0; int i; for(i=1;i<=n;i++) { if(a[i]*f[i]>mid) { if((a[i]*f[i]-mid)%f[i]==0)cnt+=(a[i]*f[i]-mid)/f[i]; else cnt+=(a[i]*f[i]-mid)/f[i]+1; } } return cnt<=k?1:0; } int main() { cin>>n>>k; int i; for(i=1;i<=n;i++) { scanf("%lld",&a[i]); } for(i=1;i<=n;i++) { scanf("%lld",&f[i]); } sort(a+1,a+n+1); sort(f+1,f+n+1,cmp); long long l=0,r=1e12,mid; while(l<r) { mid=(l+r)/2; if(check(mid)) { r=mid; } else { l=mid+1; } } cout<<l; return 0; }