3620. 大魚喫小魚
Time limit per test: 2.0 seconds
Memory limit: 256 megabytes
oxx 玩一個經典的大魚喫小魚的遊戲。
- 任意時刻只能喫大小小於等於自己的魚。
- 任何時刻都要保證魚的大小是正整數。
- 當吃了第 i 條魚之後自己的大小 x 會變爲 x+ai。
oxx 想知道他初始魚的大小至少需要多大才能喫完這 n 條魚。喫的順序可以任意。
Input
第一行一個整數 n (1≤n≤106) 表示魚的條數。
接下去 n 行,每行兩個整數 wi,ai (1≤wi≤109,−109≤ai≤109),分別表示魚的大小,和喫完魚之後會膨脹的差。
Output
輸出一個整數表示喫完所有魚的初始大小的最小值。
Examples
3 10 2 3 -1 2 5
5
Note
至少需要 5,先喫第三條變爲 10,再喫第一條變爲 12,最後喫第二條變爲 11。
一道貪心題 排序後按順序將相差的體積加起來就是答案 不過要注意:任何時刻都要保證魚的大小是正整數。
開始沒注意到這點wa了幾發
接下來就是排序方法了
- a正的優先
- 正的中 w 小的優先
- 負的中 w+a 大的優先
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
using namespace std;
struct node{
long long a,b;
};
bool cmp(node x,node y){
if(x.b>=0&&y.b>=0){
return x.a<y.a;
}
else if(x.b<0&&y.b<0){
return x.a+x.b>y.a+y.b;
}
else{
return x.b>y.b;
}
}
node s[1000000];
int main()
{
long long n;
while(~scanf("%lld",&n)){
for(int i=0;i<n;i++){
scanf("%lld %lld",&s[i].a,&s[i].b);
}
sort(s,s+n,cmp);
long long flag=1,ans=1,sum=0;
for(int i=0;i<n;i++){
if(flag<=s[i].a){
sum=s[i].a-flag;
flag=s[i].a+s[i].b;
}
else{
sum=0;
flag=flag+s[i].b;
}
if(flag<1){
sum=sum+1-flag;
flag=1;
}
ans=ans+sum;
}
printf("%lld\n",ans);
}
return 0;
}