码迷,mamicode.com
首页 > 其他好文 > 详细

codevs1198国王游戏(贪心)

时间:2016-04-23 11:35:59      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:

/*
贪心:按照左右手乘积从小到大排序
证明:
设前i-1项 算出来为S
  i:a b
i+1:c d
那么i+1处的金币为s*a/d  i处为s/b
交换 i  和  i+1 
  i:c d
i+1:a b
那么i+1处的金币为s*c/b  i处为s/d
现在我们假设交换i  和  i+1 会得到更优的解 (交换前后的第i项显然小于i+1项 所以之比较第i+1) 
则有 s*a/d > s*c/b --> a/d > c/b -->  a*b>c*d 
所以按照乘积从小到大 一定最优 
然后就是 高精度0.0 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll n,c[10001],cc[10001],b[10001],d[10001],ans[10001];
struct node
{
    int l;
    int r;
}a[1001];
int cmp(const node &x,const node &y)
{
    if(x.l*x.r<y.l*y.r)return 1;
    if(x.l*x.r>y.l*y.r)return 0;
    if(x.l*x.r==y.l*y.r)
      {
          if(x.r>y.r)return 1;
          else return 0;
      }
}
bool can()//是否需要更新最后答案 
{
    if(d[0]>ans[0])return 1;
    if(d[0]<ans[0])return 0;
    int i;
    for(i=1;i<=d[0];i++)
      if(d[i]>ans[i])return 1;
      if(d[i]<ans[i])return 0;
    return 0;
}
void cheng(int x)
{
    ll i,j,y=0;
    for(i=1;i<=c[0];i++)
      cc[i]=c[c[0]-i+1];
    for(i=1;i<=c[0];i++)
      {
        cc[i]=cc[i]*x+y;
        y=cc[i]/10;
          cc[i]=cc[i]%10;
      }
    while(y>0)//高精乘单精时 注意处理最后一位  
      {
          cc[++c[0]]=y%10;
          y=y/10;
      }
    for(i=1;i<=c[0];i++)
      c[i]=cc[c[0]+1-i];
}
void chu(int x)
{
    memset(b,0,sizeof(b));
    memset(d,0,sizeof(d));
    int i,p=0,k=1;
    for(i=1;i<=c[0];i++)
      {
          b[i]=(p*10+c[i])/x;
          p=(c[i]+p*10)%x;
      }
    b[0]=c[0];
    for(i=1;i<=b[0];i++)
      if(b[i]!=0)
        {
          k=i;
          break;
        }
    for(i=k;i<=b[0];i++)
      d[i-k+1]=b[i];
    d[0]=b[0]-k+1;
    if(can()&&d[1]!=0)
      {
          memset(ans,0,sizeof(ans));
          for(i=0;i<=d[0];i++)
            ans[i]=d[i];
      }
}
int main()
{
    cin>>n;
    ll i,j,o;
    n++;
    for(i=1;i<=n;i++)
      cin>>a[i].l>>a[i].r;
    sort(a+2,a+1+n,cmp);//排序  
    c[0]=1;c[1]=1;
    for(i=2;i<=n;i++)
      {
          cheng(a[i-1].l);//维护c 表示前面所有人的左手乘积 
          chu(a[i].r);//再÷此人的右手 记为ans 
      }
    for(j=1;j<=ans[0];j++)
      cout<<ans[j];
    return 0;
}

 

codevs1198国王游戏(贪心)

标签:

原文地址:http://www.cnblogs.com/yanlifneg/p/5424062.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!