题目链接
根据国王游戏的经验,尝试着用微扰证明,结果证明过程有误,学习了大佬题解以后发现我的证明过程确实存在问题。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
const int N=2e4+10;
typedef long long ll;
int t,n;
struct node{
ll a,b,c;
int d;
bool operator <(const node&rhs)const{
return d<rhs.d||(d==rhs.d&&d<=0&&a<rhs.a)||(d==rhs.d&&d>0&&b>rhs.b);}
}man[N];
ll sum[N];
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
_rep(i,1,n)
{
scanf("%d%d",&man[i].a,&man[i].b);
if(man[i].a-man[i].b<0)man[i].d=-1;
else if(man[i].a==man[i].b)man[i].d=0;
else man[i].d=1;
}
sort(man+1,man+n+1);
man[1].c=man[1].a+man[1].b;sum[1]=man[1].a;
_rep(i,2,n)man[i].c=max(man[i-1].c,sum[i-1]+man[i].a)+man[i].b,sum[i]=sum[i-1]+man[i].a;
printf("%lld\n",man[n].c);
}
return 0;
}
要多学习贪心的常见证明方法:
1.微扰
2.范围缩放
3.决策包容性
4.反证法
5.数学归纳法