考虑交换相邻两个二元组的影响,交换i和i+1,实际上只影响到Fi和Fi+1。
设T
方案A:Fi
方案B:Fi
①假设1
那么方案A优于方案B
②假设1
那么1
③假设1
那么1
也就是说,对于相邻两个二元组,将A
已经按A
假 设任意一种排列是{P1,P2,P3,P4....Pn},称为目标序列。{1,2,3,4,...n},称为原始序列。我们观察目标序列,从后往前,每 次将Pi从原始序列中往后交换直到它位于目标序列的位置。不难发现,序列在任意时刻都是由单调增的一段和排列好的一段组成,且每次交换都能保证结果更差。
综上,最优方案就是按A
#include"stdio.h"
#include"limits.h"
#include"stdlib.h"
#include"string.h"
int left[1001],right[1001],m_len=0,a_len,b_len;
int b[10000],e,d,n,ans[10000],max[10000];
struct stu{
int left,right;
int sum;
};
struct stu a[1001];
int cmp(const void*_a,const void*_b)
{ stu *a=(stu*)_a;
stu *b=(stu*)_b;
return a->sum-b->sum; }
int div(int m){
int i,j,x,temp=0;
memset(ans,0,sizeof(ans));
a_len=0;
x=a[m].right;
for(j=b_len-1;j>=0;j--)
{ temp=temp*10;
temp+=b[j];
if(temp>x)break; }
ans[a_len]=temp/x;
temp=temp%x;
a_len++;
for(i=j-1;i>=0;i--)
{ temp=temp*10;
temp+=b[i];
ans[a_len]=temp/x;
temp=temp%x;
a_len++;}
}
int my_cmp()
{ int i,j,result=0;
if(a_len>m_len)result=1;
else {
for(i=0;i<a_len;i++)
{ if(ans[i]>max[i]){result=1;break;}
else if(ans[i]<max[i]){result=0;break;}
}
}
if(result==1)
{ memset(max,0,sizeof(max));
for(i=0;i<a_len;i++)
max[i]=ans[i];
m_len=a_len;
}
return 0;
}
int cacu(int m)
{ int i,j;
j=a[m].left;
for(i=0;i<b_len;i++)
b[i]*=j;
for(i=0;i<b_len;i++)
{ if(b[i]>=10&&i<b_len-1)
{ b[i+1]+=b[i]/10;
b[i]=b[i]%10;
}
else if(b[i]>=10&&i==b_len-1)
{ b[i+1]+=b[i]/10;
b[i]=b[i]%10;
b_len++;
}
}
}
main()
{ int i,j;
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
scanf("%d",&n);
scanf("%d%d",&d,&e);
memset(a,0,sizeof(a));
memset(ans,0,sizeof(ans));
memset(max,0,sizeof(max));
for(i=0;i<n;i++)
{scanf("%d%d",&a[i].left,&a[i].right);
a[i].sum=a[i].left*a[i].right; }
qsort(a,n,sizeof(a[0]),cmp);
b[0]=d;b_len=1;
for(i=0;i<n;i++)
{ div(i);
my_cmp();
cacu(i); }
for(i=0;i<m_len;i++)
printf("%d",max[i]);
}