题目: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; }