ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

YbtOJ 贪心算法课堂过关 例4 国王游戏【贪心】

2020-12-26 12:32:52  阅读:342  来源: 互联网

标签:frac int YbtOJ bi -- si ff 过关 贪心


在这里插入图片描述


思路

这道题其实主要的难点是如何排序
排序之后贪心就非常简单了。

考虑贪心邻项交换
设 s i = ∏ j = 0 i a j s_i=\prod\limits_{j=0}^{i}a_j si​=j=0∏i​aj​。

首先考虑交换前,第 i i i 个上的值是 s i − 1 b i \frac {s_{i-1}}{b_i} bi​si−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+1​si−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(bi​si−1​​,bi+1​si−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+1​si−1​​, s i − 1 × a i + 1 b i \frac {s_{i-1}\times a_{i+1}}{b_i} bi​si−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+1​si−1​​,bi​si−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} bi​si−1​​<bi​si−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+1​si−1​​<bi+1​si−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+1​si−1​×ai​​<bi​si−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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有