【算法】贪心+高精度
【题解】学自:http://blog.csdn.net/greatwjj/article/details/12129439
相邻两个人的顺序对前面的人和后面的人的钱都没影响。
令两个人分别为i和i+1,左手数字为a[i],a[i+1],右手数字为b[i],b[i+1],钱为w[i],w[i+1]。
令sum[i]为1...n的左手数字的总乘积。
w[i]=sum[i-1]/b[i]
w[i+1]=sum[i]/b[i+1]
因为sum[i]=sum[i-1]*a[i]
所以w[i+1]=sum[i-1]*a[i]/b[i+1]=w[i]*a[i]*b[i]/b[i+1]
由此可知w[i+1]的大小只与a[i],b[i],a[i]*b[i](即w[i])有关。
所以按a[i]*b[i]从小到大排序即可。
答案最大可以达到10000^1000即10^4000,要用高精度(T_T)
#include<cstdio> #include<algorithm> using namespace std; const int maxn=1010,maxlen=5000; struct cyc{int a,b,c;}a[maxn]; int n,lens,x,lmax,lena; int sum[maxlen],ans[maxlen],maxs[maxlen]; bool cmp(cyc a,cyc b) {return a.c<b.c;} void cheng(int numi) { int num=a[numi].a;x=0; for(int i=1;i<=lens;i++) { x+=sum[i]*num; sum[i]=x%10; x/=10; } while(x>0)sum[++lens]=x%10,x/=10; // printf("1...%d * lens=%d\n",numi,lens); // for(int i=1;i<=lens;i++)printf("%d",sum[i]);printf("\n"); } void divs(int numi) { int num=a[numi].b;x=0; for(int i=lens;i>=1;i--) { x=x*10+sum[i]; ans[i]=x/num; x%=num; } lena=lens; while(ans[lena]==0&&lena>1)lena--; // printf("1...%d-1/%d / lens=%d\n",numi,numi,lena); // for(int i=1;i<=lena;i++)printf("%d",ans[i]);printf("\n"); bool f=1; if(lena>lmax)f=0;else if(lena<lmax)f=1;else for(int i=lena;i>=1;i--) if(ans[i]>maxs[i]){f=0;break;}else if(ans[i]<maxs[i]){f=1;break;} if(!f) { for(int i=1;i<=lena;i++)maxs[i]=ans[i]; lmax=lena; } } int main() { scanf("%d",&n); for(int i=1;i<=n+1;i++)scanf("%d%d",&a[i].a,&a[i].b),a[i].c=a[i].a*a[i].b; sort(a+2,a+n+2,cmp);//for(int i=1;i<=n+1;i++)printf("%d %d\n",a[i].a,a[i].b); sum[(lens=1)]=1;cheng(1);maxs[(lmax=1)]=0; for(int i=2;i<=n+1;i++)divs(i),cheng(i); for(int i=lmax;i>=1;i--)printf("%d",maxs[i]); return 0; }
时间: 2024-10-03 07:51:44