YbtOJ 贪心算法课堂过关 例4 国王游戏【贪心】
作者:互联网
思路
这道题其实主要的难点是如何排序。
排序之后贪心就非常简单了。
考虑贪心邻项交换
设
s
i
=
∏
j
=
0
i
a
j
s_i=\prod\limits_{j=0}^{i}a_j
si=j=0∏iaj。
首先考虑交换前,第
i
i
i 个上的值是
s
i
−
1
b
i
\frac {s_{i-1}}{b_i}
bisi−1,第
i
+
1
i+1
i+1个 是
s
i
−
1
×
a
i
b
i
+
1
\frac {s_{i-1}\times a_i}{b_{i+1}}
bi+1si−1×ai
a
n
s
1
=
max
(
s
i
−
1
b
i
,
s
i
−
1
×
a
i
b
i
+
1
)
ans_1=\max(\frac {s_{i-1}}{b_i},\frac {s_{i-1}\times a_i}{b_{i+1}})
ans1=max(bisi−1,bi+1si−1×ai)
交换后
i
i
i 的位置就变成了
i
+
1
i+1
i+1,
i
+
1
i+1
i+1 的位置就变成了
i
i
i。
值分别为
s
i
−
1
b
i
+
1
\frac {s_{i-1}}{b_{i+1}}
bi+1si−1,
s
i
−
1
×
a
i
+
1
b
i
\frac {s_{i-1}\times a_{i+1}}{b_i}
bisi−1×ai+1
a
n
s
2
=
max
(
s
i
−
1
b
i
+
1
,
s
i
−
1
×
a
i
+
1
b
i
)
ans_2=\max(\frac {s_{i-1}}{b_{i+1}},\frac {s_{i-1}\times a_{i+1}}{b_i})
ans2=max(bi+1si−1,bisi−1×ai+1)
显然
s
i
−
1
b
i
<
s
i
−
1
×
a
i
+
1
b
i
\frac {s_{i-1}}{b_i} < \frac {s_{i-1}\times a_{i+1}}{b_i}
bisi−1<bisi−1×ai+1
并且
s
i
−
1
b
i
+
1
<
s
i
−
1
×
a
i
b
i
+
1
\frac {s_{i-1}}{b_{i+1}} <\frac {s_{i-1}\times a_i}{b_{i+1}}
bi+1si−1<bi+1si−1×ai
如果
a
n
s
1
<
a
n
s
2
ans_1<ans_2
ans1<ans2
那么
s
i
−
1
×
a
i
b
i
+
1
<
s
i
−
1
×
a
i
+
1
b
i
)
\frac {s_{i-1}\times a_i}{b_{i+1}}<\frac {s_{i-1}\times a_{i+1}}{b_i})
bi+1si−1×ai<bisi−1×ai+1)
通过化简,得:
a
i
⋅
b
i
<
a
i
+
1
⋅
b
i
+
1
a_i\cdot b_i<a_{i+1}\cdot b_{i+1}
ai⋅bi<ai+1⋅bi+1
由此可见,对
a
∗
b
a*b
a∗b 进行关键字排序就可以了。
这题还需要高精度!!!
C o d e Code Code
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
long long ff[10100],f[10100],ans[10100];
long long n,js=1;
struct node
{
long long x,y;
}a[1000010];
bool cmp(const node&d,const node&dd)
{
return d.x*d.y<dd.x*dd.y;
}
void gjc(int x)
{
int jw=0;
for(int i=1; i<=10000; i++)
{
f[i]=f[i]*x+jw;
jw=f[i]/10;
f[i]%=10;
}
}
void gju(int x)
{
int j=10000,jw=0;
while(f[j]==0)
j--;
for(int i=j; i>=1; i--)
{
ff[i]=(f[i]+jw*10);
jw=ff[i]%x;
ff[i]/=x;
}
}
void gjbj()
{
int j=10000;
while(ans[j]==0)
j--;
int jj=10000;
while(ff[jj]==0)
jj--;
if(jj>j)
for(int i=1; i<=jj; i++)
ans[i]=ff[i];
else if(jj==j)
for(int i=jj; i>=1; i--)
if(ans[i]<ff[i])
{
for(int i=1; i<=jj; i++)
ans[i]=ff[i];
break;
}
else if(ans[i]>ff[i])
break;
memset(ff,0,sizeof(ff));
}
int main()
{
cin>>n;
for(int i=1; i<=n+1; i++)
scanf("%lld%lld",&a[i].x,&a[i].y);
sort(a+2,a+2+n,cmp);
f[1]=1;
for(int i=2; i<=n+1; i++)
{
gjc(a[i-1].x);
gju(a[i].y);
gjbj();
}
int j=10000;
while(ans[j]==0)
j--;
for(int i=j; i>=1; i--)
cout<<ans[i];
return 0;
}
标签:frac,int,YbtOJ,bi,--,si,ff,过关,贪心 来源: https://blog.csdn.net/Jackma_mayichao/article/details/111722624