Codevs1198 国王游戏

本文介绍了一种使用贪心算法解决特定序列优化问题的方法。通过将序列中元素进行排序并选择最优交换,实现整体优化目标。文章详细阐述了算法逻辑、关键步骤及其实现代码,特别强调了高精度计算的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 思路:贪心。由题意可知,交换相邻两个人对于其他人并无影响。设这两个人按顺序分别为{a1,b1},{a2,b2},交换前是max{sum*1/b1,sum*a1/b2},交换后是max{sum*1/b2,sum*a2/b1},而分母为1的项一定不会被最大值考虑到,则需要考虑max{sum*a2/b1,sum*a1/b2},即max{a2/b1,a1/b2}。如果不交换更优,则有a1/b2<a2/b1,即a1×b1<a2×b2。所以,以aibi为关键字进行从小到大排序,会得到最优解。最后只需扫描一遍序列就行了。由于乘积可能很大,所以需要使用高精度计算。

  • 代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1005;
struct node
{    
    int a,b;
    node(int a=0,int b=0):a(a),b(b){}
    bool operator < (const node &x) const
    {
        return a*b<x.a*x.b;
    }
};
struct bignum
{
    int len,a[5000];
    bignum()
    {        
        len=1;
        memset(a,0,sizeof(a));
    }
    bignum operator * (int num)
    {
        len++;
        int jinwei=0;
        for (int i=1;i<=len;++i)
        {
            a[i]=a[i]*num+jinwei;
            jinwei=a[i]/100000;
            a[i]%=100000;
        }
        if (a[len]==0)
          len--;
        return *this;
    }
    bool operator < (const bignum &b) const
    {
        if (b.len!=len)
          return len<b.len ? 1:0;
        for (int i=len;i>=1;--i)
          if (a[i]!=b.a[i])
            return a[i]<b.a[i] ? 1:0;
        return 0;
    }
    bignum operator / (int num)
    {
        bignum c=*this;
        int jiewei=0;
        for (int i=len;i>=1;--i)
        {
            jiewei=a[i]+100000*jiewei;
            c.a[i]=jiewei/num;
            jiewei%=num;
        }
        while (c.a[c.len]==0)
          c.len--;
        return c;
    }
    bignum operator *= (int num)
    {
        *this=*this*num;
        return *this;
    } 
};

void print(bignum x)
{
    printf("%d",x.a[x.len]);
    for (int i=x.len-1;i>=1;--i)
      printf("%05d",x.a[i]);
}

int n;
node man[maxn];

int main()
{
    scanf("%d",&n);
    scanf("%d%d",&man[1].a,&man[1].b);
    for (int i=2;i<=n+1;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        man[i]=node(a,b);
    }
    sort(man+2,man+n+2);
    bignum ans,sum;
    sum.a[1]=man[1].a;
    for (int i=2;i<=n+1;++i)
    {
        ans=max(sum/man[i].b,ans);
        sum*=man[i].a;
    }
    print(ans);
    return 0;
}       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值