国王游戏

QAQ
(贪心)首先,交换相邻两个大臣只会对这两个大臣造成影响,并不会对其他大臣造成影响。

我们考虑大臣i和i+1,设他们左手数字分别为A[i]和A[i+1],右手分别为B[i]和B[i+1],前i-1个大臣和国王左手的数的乘积为S,切A[i]B[i]<=A[i+1]B[i+1]。

原来两个大臣能得到的金币数分别为S/B[i],S*A[i]/B[i+1]。

如果交换,则第一个大臣现在能得到S*A[i+1]/B[i],第二个能得到S/B[i+1]。

由于A[i]B[i]<=A[i+1]B[i+1],所以S*A[i]*B[i]<=S*A[i+1]*B[i+1],所以S*A[i]/B[i+1]<=S*A[i+1]/B[i]。

由此可得大臣以A[i]B[i]从小到大排序,答案越小。

而S*A[i+1]/B[i]>=S/B[i],S*A[i]/B[i+1]>=S/B[i+1],故最大的答案为后面那个大臣的,也保证了答案的正确性。

然后60的数据long long可过。
100高精度无敌。

#include 
#include 
#include 
#include 
#define ll long long
using namespace std;
ll a[99999],b[99999];
ll ans[99999],cnt_ans;
ll x[99999],cnt=1;
ll w[99999],qcnt;
ll n;
ll ga,gb;
struct node{
    ll a,b,id;
    ll c;
}haha[99999];
bool comp(const node&x,const node&y)
{
    return x.cvoid adx(ll k)
{
   for(int i=1;i<=cnt;i++)
    x[i]*=k;

   for(int i=1;i<=cnt;i++)
    if(x[i]>=10000)
     x[i+1]+=(x[i]/10000),x[i]%=10000;
    if(x[cnt+1]) cnt++;
}
bool pd()
{
    for(int i=qcnt;i>=1;i--)
    {
        if(w[i]>ans[i]) return 1;
        if(w[i]return 0;
    }
   return 0;
}
void bx(ll k)
{
    memset(w,0,sizeof(w));
    qcnt=cnt;
    for(int i=cnt;i>=1;i--)
    {
        w[i]+=x[i];
        if(i!=1) w[i-1]+=((w[i]%k)*10000);
        w[i]/=k;
    }
    if(w[qcnt]==0&&qcnt>1) qcnt--;
    /*for(int i=cnt;i>=1;i--)
     printf("%lld",x[i]);
    printf(" ");
    for(int i=qcnt;i>=1;i--)
     printf("%lld",w[i]);
    printf(" %lld",k);
    puts("");*/
    if(qcnt>cnt_ans)
    {
        cnt_ans=qcnt;
        for(int i=1;i<=qcnt;i++)
         ans[i]=w[i];
    }
    else
     if(qcnt==cnt_ans)
      {
        if(pd())
        {
          cnt_ans=qcnt;
          for(int i=1;i<=qcnt;i++)
          ans[i]=w[i];
        }
      }
}
int main()
{
    //freopen("game.in","r",stdin);freopen("game.out","w",stdout);
    scanf("%lld",&n);
    scanf("%lld%d",&ga,&gb);
    for(int i=1;i<=n;i++)
     scanf("%lld%lld",&haha[i].a,&haha[i].b),haha[i].c=haha[i].a*haha[i].b;
    x[1]=1;
    sort(haha+1,haha+n+1,comp);
    x[1]=ga;
    for(int i=1;i<=n;i++)
     bx(haha[i].b),adx(haha[i].a);
    printf("%lld",ans[cnt_ans]);
    for(int i=cnt_ans-1;i>=1;i--)
     printf("%04lld",ans[i]);
    /*for(int i=1;i<=n;i++)
     printf("%lld ",haha[i].id);*/
}

你可能感兴趣的:(题目分析,贪心)