信息学奥赛一本通 1870:【12NOIP提高组】国王游戏 | 洛谷 P1080 [NOIP 2012 提高组] 国王游戏

【题目链接】

ybt 1870:【12NOIP提高组】国王游戏
洛谷 P1080 [NOIP 2012 提高组] 国王游戏

【题目考点】

1. 贪心算法

  • 邻项交换法
    假设最的贪心选择序列中存在相邻元素不符合贪心选择策略,证明如果将二者交换后结果更优或与之前相同,那么就可以不断交换这样的相邻元素直到序列符合贪心选择策略。

2. 高精度

【解题思路】

思路1:通过邻项交换法推测贪心选择

每个大臣可以抽象为一个元素,每个元素是一个数对,原序列中第 i i i个大臣左手的数为 l i l_i li,右手的数为 r i r_i ri。设 s i = ∏ j = 1 i l j s_i=\prod_{j=1}^{i}l_j si=j=1ilj,将第 i i i个大臣获得的钱数叫做元素的特征值,为: s i − 1 r i \dfrac{s_{i-1}}{r_i} risi1。大臣的排列就是元素序列。
所求结果为:对于所有元素的排列,存在一种排列,其各元素的最大特征值相比于其它排列的最大特征值是最小的。求该排列下各元素最大的特征值。
基于邻项交换法,思考贪心策略。
假设能取得最优解的的序列中,任选第 i i i元素,与其相邻的下一个元素为第 j j j元素。
i i i元素的特征值为: s i − 1 r i \frac{s_{i-1}}{r_i} risi1,第 j j j元素的特征值为: s i r j \frac{s_i}{r_j} rjsi
在序列中交换第 i i i和第 j j j元素后:
i i i元素的特征值为: s i r i \frac{s_i}{r_i} risi
i + 1 i+1 i+1元素的特征值为: s i − 1 r j \frac{s_{i-1}}{r_j} rjsi1

由于交换前为最优解,因此要保证交换前第 i i i i + 1 i+1 i+1元素的特征值的最大值小于等于交换后第 i i i i + 1 i+1 i+1元素的特征值的最大值,因此:
m a x ( s i − 1 r i , s i r j ) ≤ m a x ( s i − 1 ⋅ l j r i , s i − 1 r j ) max(\dfrac{s_{i-1}}{r_i}, \dfrac{s_i}{r_{j}})\le max(\dfrac{s_{i-1}\cdot l_j}{r_i}, \dfrac{s_{i-1}}{r_{j}}) max(risi1,rjsi)max(risi1lj,rjsi1)
两边乘以 r i r j s i − 1 \dfrac{r_ir_j}{s_{i-1}} si1rirj,得:
m a x ( r j , l i r i ) ≤ m a x ( l j r j , r i ) max(r_j, l_ir_i)\le max(l_jr_j, r_i) max(rj,liri)max(ljrj,ri)
sort排序的比较规则必须满足严格弱序具体原理见该博文:C++: Strict Weak Ordering
而比较规则 m a x ( r j , l i r i ) ≤ m a x ( l j r j , r i ) max(r_j, l_ir_i)\le max(l_jr_j, r_i) max(rj,liri)max(ljrj,ri)不满足严格弱序中的非自反性,因此需要得到一个符合该关系的更严格的偏序关系。
可以尝试使用 m a x ( r j , l i r i ) < m a x ( l j r j , r i ) max(r_j, l_ir_i)< max(l_jr_j, r_i) max(rj,liri)<max(ljrj,ri),但该关系不满足不可比性传递性。
进一步分类讨论 m a x ( r j , l i r i ) ≤ m a x ( l j r j , r i ) max(r_j, l_ir_i)\le max(l_jr_j, r_i) max(rj,liri)max(ljrj,ri)

  1. 如果 r j < l i r i ∧ r i < l j r j r_j<l_ir_i\land r_i<l_jr_j rj<liriri<ljrj:那么该关系等价于 l i r i ≤ l j r j l_ir_i\le l_jr_j liriljrj
  2. 如果 r j < l i r i ∧ r i ≥ l j r j r_j<l_ir_i\land r_i\ge l_jr_j rj<liririljrj:那么该关系等价于 l i r i ≤ r i l_ir_i\le r_i liriri,已知 r i > 0 r_i>0 ri>0,所以该关系等价于 l i ≤ 1 l_i\le 1 li1
  3. 如果 r j ≥ l i r i ∧ r i < l j r j r_j\ge l_ir_i\land r_i<l_jr_j rjliriri<ljrj:那么该关系等价于 r j ≤ l j r j r_j\le l_jr_j rjljrj,即 l j ≥ 1 l_j\ge1 lj1
  4. 如果 r j ≥ l i r i ∧ r i ≥ l j r j r_j\ge l_ir_i\land r_i\ge l_jr_j rjliririljrj,那么该关系等价于 r j ≤ r i r_j\le r_i rjri

经过讨论得到线索,某些情况下原关系 m a x ( r j , l i r i ) ≤ m a x ( l j r j , r i ) max(r_j, l_ir_i)\le max(l_jr_j, r_i) max(rj,liri)max(ljrj,ri)
等价于 l i r i ≤ l j r j l_ir_i\le l_jr_j liriljrj,可以排序的比较关系必须满足非自反性,所以取 l i r i < l j r j l_ir_i< l_jr_j liri<ljrj
那么猜测:只要相邻 i , j i,j i,j两项满足 l i r i < l j r j l_ir_i<l_jr_j liri<ljrj,那么一定满足 m a x ( r j , l i r i ) ≤ m a x ( l j r j , r i ) max(r_j,l_ir_i)\le max(l_jr_j, r_i) max(rj,liri)max(ljrj,ri)

已知 l i , r i , l j , r j l_i, r_i, l_j, r_j li,ri,lj,rj都为正整数,且满足 l i r i < l j r j l_ir_i<l_jr_j liri<ljrj

  • 如果 l j r j ≥ r i l_j r_j\ge r_i ljrjri,那么 m a x ( l j r j , r i ) = l j r j max(l_jr_j, r_i)=l_j r_j max(ljrj,ri)=ljrj
    • 如果 r j > l i r i r_j> l_i r_i rj>liri,那么 m a x ( r j , l i r i ) = r j max(r_j,l_ir_i)=r_j max(rj,liri)=rj m a x ( r j , l i r i ) ≤ m a x ( l j r j , r i ) max(r_j,l_ir_i)\le max(l_jr_j, r_i) max(rj,liri)max(ljrj,ri) r j ≤ l j r j r_j\le l_j r_j rjljrj,即 l j ≥ 1 l_j\ge 1 lj1,表达式成立。
    • 如果 r j ≤ l i r i r_j\le l_i r_i rjliri,那么 m a x ( r j , l i r i ) = l i r i max(r_j,l_ir_i)=l_ir_i max(rj,liri)=liri m a x ( r j , l i r i ) ≤ m a x ( l j r j , r i ) max(r_j,l_ir_i)\le max(l_jr_j, r_i) max(rj,liri)max(ljrj,ri) l i r i ≤ l j r j l_i r_i\le l_j r_j liriljrj,表达式成立。
  • 如果 l j r j < r i l_j r_j< r_i ljrj<ri,已知 l i r i < l j r j l_ir_i<l_jr_j liri<ljrj,那么 r i < l j r j l i ≤ l j r j r_i<\frac{l_jr_j}{l_i}\le l_jr_j ri<liljrjljrj,因此不存在 l j r j < r i l_j r_j< r_i ljrj<ri的情况。

因此可以将序列按照比较规则 l i r i < l j r j l_ir_i<l_jr_j liri<ljrj排序,而后进行贪心选择。

思路2: 直接猜测贪心策略

根据第 i i i元素的特征值为: s i − 1 r i = s i l i r i \dfrac{s_{i-1}}{r_i}=\dfrac{s_i}{l_ir_i} risi1=lirisi
n n n个元素为 s i l n r n \dfrac{s_i}{l_nr_n} lnrnsi,分子是固定的,第 n n n元素的两数乘积越大,特征值越小。所以第 n n n元素应该两数乘积最大,依次类推第 n − 1 n-1 n1元素的两数乘积倒数第二大。。。猜想应该按照每个元素的两数乘积排序,如果 i , j i,j i,j是相邻两项,那么相邻两项应该满足: l i r i ≤ l j r j l_ir_i\le l_{j}r_{j} liriljrj
而后通过邻项交换法证明该贪心策略成立。
假设第 i i i元素和与其相邻的第 j j j元素(即第 i + 1 i+1 i+1元素)不满足贪心策略,即 l i r i > l j r j l_ir_i>l_{j}r_{j} liri>ljrj
i i i元素的特征值为: s i − 1 r i \dfrac{s_{i-1}}{r_i} risi1

j j j元素的特征值为: s i r j \dfrac{s_i}{r_{j}} rjsi
在序列中交换第 i i i和第 j j j元素后:
i i i元素的特征值为: s i − 1 ⋅ l j r i = s i − 1 ⋅ l j r j r i r j < s i − 1 ⋅ l i r i r i r j = s i r j \dfrac{s_{i-1}\cdot l_{j}}{r_i}=\dfrac{s_{i-1}\cdot l_{j}r_{j}}{r_ir_{j}}<\dfrac{s_{i-1}\cdot l_{i}r_{i}}{r_ir_{j}}=\dfrac{s_i}{r_{j}} risi1lj=rirjsi1ljrj<rirjsi1liri=rjsi
即第 i i i元素的特征值在交换后小于交换前第 j j j元素的特征值。
j j j元素的特征值为: s i − 1 r j ≤ s i r j \dfrac{s_{i-1}}{r_{j}} \le \dfrac{s_i}{r_{j}} rjsi1rjsi
即第 j j j元素的特征值在交换后小于等于交换前第 j j j元素的特征值。
因此两元素交换后,最大的特征值没有增大,仍然是最优解。可以不断交换不符合贪心选择顺序的相邻项,直到整个序列符合贪心策略。

因此贪心选择策略可以为:每次选择 l i r i l_ir_i liri最小的元素。具体做法是:将所有元素按 l i r i l_ir_i liri从小到大排序。而后计算各元素的特征值,比较求出各元素特征值的最大值,即为本题结果。

【题解代码】

解法1:每次选择 l i r i l_ir_i liri最小的元素

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1005;
struct Peo
{
	int l, r;
} a[N];
struct HPN
{
	int a[4100] = {};//1000个10000相乘,结果最多4000位
	HPN(){}
	HPN(int v)
	{
		int len = 0;
		do
		{
			a[++len] = v%10;
			v /= 10;
		} while(v > 0);
		a[0] = len;
	}
	int& operator [] (int i)
	{
		return a[i];
	}
	void setLen(int i)
	{
		while(a[i] == 0 && i > 1)
			i--;
		a[0] = i;
	}
	int numcmp(int *a, int *b)
	{
		if(a[0] > b[0])
			return 1;
		else if(a[0] < b[0])
			return -1;
		else
		{
			for(int i = a[0]; i >= 1; --i)
			{
				if(a[i] > b[i])
					return 1;
				else if(a[i] < b[i])
					return -1;
			}
			return 0;
		}
	}	
	bool operator < (HPN b)
	{
		return numcmp(a, b.a) < 0;
	}
	void operator *= (int b)
	{
		int i, c = 0;
		for(i = 1; i <= a[0]; ++i)
		{
			a[i] = a[i]*b+c;
			c = a[i]/10;
			a[i] %= 10;
		}
		while(c > 0)
		{
			a[i++] = c%10;
			c /= 10;
		}
		setLen(i);
	}
	HPN operator / (int b)
	{
		HPN r;
		int x = 0;
		for(int i = a[0]; i >= 1; --i)
		{
			x = x*10+a[i];
			r[i] = x/b;
			x %= b;
		}
		r.setLen(a[0]);
		return r;
	}
	void show()
	{
		for(int i = a[0]; i >= 1; --i)
			cout << a[i];
		cout << endl;
	}
};
int n;
bool cmp(Peo a, Peo b)
{
	return a.l*a.r < b.l*b.r;
} 
int main()
{
	cin >> n;
	for(int i = 0; i <= n; ++i)//a[0]为国王 
		cin >> a[i].l >> a[i].r;
	sort(a+1, a+1+n, cmp);//对所有大臣排序
	HPN s(a[0].l), ans(0);
	for(int i = 1; i <= n; ++i)
	{
		if(ans < s/a[i].r)
			ans = s/a[i].r;
		s *= a[i].l;
	}
	ans.show();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值