【noip 2012】国王游戏 贪心+高精度

哎,还好今天的高精度没有写挂,但是其实可以只用数组维护的,当年背的一个版,用到现在用习惯了

贪心证明:第i个大臣左右手写的是a,b第j个大臣左右手写的是x,y,i之前的左手分数为q,i->j之间为p那么现在最大分数是max(q/b,q*a*p/y) 化简以后:max(1/b,a*p/y)又因为是向下取整所以1/a==0,1一定小于x*p/y(至于1的情况 自己手写一下发现并不影响)同理交换之后 max(q/y,q*p*x/b)->max(1/y,p*x/b)->p*x/b即是比较min(p*x/b,a*p/y)->min(x/b,a/y)要求x/b x*y

#include
#include
#include
#include
#define LL long long
#define maxn 1010
#define base 10000
using namespace std;
int n;
struct node{
	int a,b;
	LL p;
	bool operator <(const node& b)const{return p1)len--;}
	Bigint Write(char* s){
		memset(c,0,sizeof(c));len=1;
		int k=1,ll=strlen(s);
		for(int i=ll-1;i>=0;i--){
			c[len]+=(s[i]-'0')*k;
			k*=10;
			if(k==base){
				k=1,len++;
			}
		}
		Zero();
		return *this;
	}
	void read(){
		char s[10020];
		scanf("%s",s);
		Write(s);
	}
	void Print(){
		Zero();
		printf("%d",c[len]);
		for(int i=len-1;i>=1;i--){
			printf("%04d",c[i]);
		}
	}
	bool operator >(Bigint& b){
		Zero();b.Zero();
		if(len!=b.len)return  len>b.len;
		for(int i=len;i>=1;i--){
			if(c[i]!=b.c[i])return c[i]>b.c[i];
		}
		return false;
	}
	Bigint operator = (const int& b){
		memset(c,0,sizeof(c)),len=1;
		char s[10020];
		sprintf(s,"%d",b);
		Write(s);
		return *this;
	}
	Bigint operator *(const int & b){
		Bigint r;
		r.len=len+4;
		for(int i=1;i<=r.len;i++){
			r.c[i]+=c[i]*b;
		}
		for(int i=1;i<=r.len;i++){
			r.c[i+1]+=r.c[i]/base;
			r.c[i]%=base;
		}
		r.Zero();
		return r;
	}
	Bigint operator / (const int& b){
		Bigint r,k;
		k=*this;
		r.len=len+1;
		for(int i=len;i>=1;i--){
			r.c[i]=k.c[i]/b;
			if(i!=1)k.c[i-1]+=(k.c[i]%b*base);
			k.c[i]/=b;
		}
		r.Zero();
		return  r;
	}
};

void solve(){
	Bigint now;
	Bigint ans;
	Bigint r;
	now=nod[0].a;
	for(int i=1;i<=n;i++){
		r=now/nod[i].b;
		if(r>ans)ans=r;
		now=now*nod[i].a;
	}
	ans.Print();
}

int main(){
	scanf("%d",&n);
	scanf("%d%d",&nod[0].a,&nod[0].b);
	for(int i=1;i<=n;i++)scanf("%d%d",&nod[i].a,&nod[i].b),nod[i].p=(LL)nod[i].a*nod[i].b;
	sort(nod+1,nod+1+n);
	solve();
	return 0;
}/*
3
1 1
2 3
7 4
4 6
*/


你可能感兴趣的:(ac之路,noip模拟)