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

luoguP1080 国王游戏 (贪心+高精度)

时间:2019-02-02 12:33:35      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:using   一个   最小值   main   综合   tps   一个人   span   一段   

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

参考:https://www.luogu.org/problemnew/solution/P1080

思路:这道题的考点是贪心和高精度。

贪心部分:

…(设这一段乘积为X1)…(设这一段乘积为Y2)
L1 R1
…(设这一段乘积为X2) …(设这一段乘积为Y2)
L2 R2
由上面这张表格可以知道这样的情况时:

第一个人所得的金币数为X1/R1;

第二个人所得的金币数为X1×L1×X2/R2;

所以最小值为 max(X1/R1, X1×L1×X2/R2);


然后交换两个人的位置


…(这一段乘积为X1)…(这一段乘积为Y2)
L2 R2
…(这一段乘积为X2) …(这一段乘积为Y2)
L1 R1
由上面这张表格可以知道交换后的情况时:

第一个人所得的金币数为X1×L2×X2/R1;

第二个人所得的金币数为X1/R2;

所以此时最小值为max(X1×L2×X2/R1, X1/R2);

综合上面两种情况:

如果变换之前的情况要优于变换之后的情况,那么

max(X1/R1, X1×L1×X2/R2) < max(X1×L2×X2/R1, X1/R2);

而X1/R1 < X1×L2×X2/R1 恒成立;

X1×L1×X2/R2 > X1/R2;

所以上述条件成立时

必须有X1×L1×X2/R2 < X1×L2×X2/R1 恒成立;所以化简可得 L1×R1 < L2×R2恒成立。

综上,很容易想到Li×Ri越大的应该排在越后面,所以对数据排个序就行。

另外就是高精度,数据最大可能达到10的4000次方,故需要使用高精度,这种高精度方法是参考的别人的,比较方便巧妙,不需要花费时间进行整数与字符串的转化。

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 struct node{
 6     int a,b;
 7     bool operator < (const node& other) const{
 8         return a*b<other.a*other.b;
 9     }
10 }dat[1005];
11 
12 int n,in=1;
13 int hp[4005];
14 
15 void mul(int k){
16     for(int i=1;i<=in;i++)
17         hp[i]*=dat[k].a;
18     for(int i=1;i<=in;i++){
19         hp[i+1]+=hp[i]/10;
20         hp[i]%=10;
21     }
22     in++;
23     while(hp[in]>9){
24         hp[in+1]=hp[in]/10;
25         hp[in]%=10;
26         in++;
27     }
28     if(hp[in]==0)
29         in--;
30 }
31 
32 void div(){
33     for(int i=in;i>=1;i--){
34         hp[i-1]+=((hp[i]%dat[n].b)*10);
35         hp[i]/=dat[n].b;    
36     }
37     while(hp[in]==0)
38         in--;
39 }
40 
41 int main(){
42     scanf("%d",&n);
43     for(int i=0;i<=n;i++)
44         scanf("%d%d",&dat[i].a,&dat[i].b);
45     sort(dat+1,dat+n+1);
46     hp[1]=dat[0].a;
47     for(int i=1;i<n;i++)
48         mul(i);
49     div();
50     if(in==0)
51         printf("1");  //最终数组长度为0,由于每个人都会得到赏金,故每个人最多分到1赏金
52     else
53         for(int i=in;i>=1;i--)
54             printf("%d",hp[i]);
55     printf("\n");
56     return 0;
57 }

 

luoguP1080 国王游戏 (贪心+高精度)

标签:using   一个   最小值   main   综合   tps   一个人   span   一段   

原文地址:https://www.cnblogs.com/FrankChen831X/p/10348183.html

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