题目:https://www.luogu.org/problemnew/show/P1080

冒泡排序的思想证明a [ i ] * b [ i ]小的放在前面。

压位高精乘的进位处理!!见代码。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int INF=10000;
typedef long long ll;
ll n,gb,ljc[1005],max,tmp[1005],ans[1005];
char tp[5];
struct Node{
    ll a,b,w;
}r[1005];
bool cmp(Node x,Node y)
{
    return x.w<y.w;
}
void chu(ll b)
{
    ll x=0;
    tmp[0]=ljc[0];
    for(ll i=ljc[0];i;i--)
    {
        ll s=ljc[i]+x*INF;
        tmp[i]=s/b;
        x=s%b;
    }
    while(!tmp[tmp[0]]&&tmp[0]>1)tmp[0]--;
}
bool comp(ll ans[],ll b[])
{
    if(ans[0]>b[0])return 0;
    if(ans[0]<b[0])return 1;
    for(ll i=ans[0];i;i--)
    {
        if(ans[i]>b[i])return 0;
        if(ans[i]<b[i])return 1;
    }
    return 0;
}
void mul(ll a)
{
    ll x=0;//////////原本没有用x记录进位,直接ljc[i+1]+=s/INF 
    for(ll i=1;i<=ljc[0];i++)
    {
        ll s=ljc[i]*a+x;        ////但这样会在这一步时把x也乘了a!!! 
        x=s/INF;
        ljc[i]=s%INF;
    }
    if(x)ljc[0]++,ljc[ljc[0]]=x;//至多进一位 
}
int main()
{
    scanf("%lld%lld%lld",&n,&ljc[1],&gb);
    ljc[0]=1;
    for(ll i=1;i<=n;i++)
    {
        scanf("%lld%lld",&r[i].a,&r[i].b);
        r[i].w=r[i].a*r[i].b;
    }
    sort(r+1,r+n+1,cmp);
    for(ll i=1;i<=n;i++)
    {
        memset(tmp,0,sizeof tmp);
        chu(r[i].b);
        if(comp(ans,tmp))memcpy(ans,tmp,sizeof tmp);
        mul(r[i].a);
    }
    printf("%lld",ans[ans[0]]);
    for(ll i=ans[0]-1;i;i--)
    {
        printf("%lld",ans[i]/1000);
        printf("%lld",ans[i]/100%10);
        printf("%lld",ans[i]/10%10);
        printf("%lld",ans[i]%10);
    }
    return 0;
}