相邻两项比较的方法深入人心(

原题 Link

感谢那个第一位写出此题正解且没有被 hack 掉的大佬。


建议这一道题目和国王游戏一起看

但是这两道题目在算法上却有一些本质的不同。(这一篇会主要讲讲)

整理做法

首先看到安排顺序,考虑进行相邻两项的比较,跟国王游戏的套路没啥区别;

再来看一眼题目中给出的表达式:

\[c_{i}= \begin{cases} a_{1}+b_{1} , & \ i=1 \\ \max \left \{ c_{i-1},\sum_{j=1}^{i}a_{j} \right \}+b_{i}, & \ 2\leq i \leq n \end{cases} \]

这其实就足以证明越往后钱就约多,然而皇后却希望奖金最多的大臣得到的钱要尽量少,所以我们要让后面的大臣的奖金尽量少;

相邻两项之间的比较

国王游戏这一道题目我们是比较的

\[\max(b_{i+1},a_i\cdot b_i)<\max(b_i,a_{i+1}\cdot b_{i+1}) \]

说简单点也就是比较交换前的 \(\max(c_i,c_j)\) 和交换后的 \(\max(c_i,c_j)\) 但是这里我们显然是不用这么去比较的,其他题解都讲的很清楚力,由于 \(c_i\) 相对于其他的量来说是一只在变化的,所以,我们只需要比较 交换前的 \(c_j\) 和交换后的 \(c_i\) 就可以了;

然后其实这一部分比较就是一个一直化简、举例的过程,别的题解讲的很透了,这里不说了,总之我们珂以推出下面的柿子:

\[\max(a_i,b_j) \le \max(a_j,b_i) \]

(注:这里满足的条件是 \(j=i+1\)

从这里我们可以得出要来:

\(\min(a_i,b_j) \le \max(a_j,b_i)\) 那么调换一下 \(i\)\(j\) 的位置就可;

这个不受这两个大臣前后的大臣的影响。

但是为了证实这个是正确的,我们就需要考虑一个极端的可能性:

由于上面那个柿子和 \(a_i\)\(b_i\) 的大小有着直接的关系,我们不妨分情况来看一下:

  • \(a_i \le b_i\),因此,\(a_j \le a_i\) 并且 \(a_j \le b_j\) 不难看出,这一组要按照 \(a\) 的升序 排列;

  • \(a_i>b_i\),则有 \(b_j \ge b_i\) 或者 \(b_j \ge a_j\) 这一组要按照 \(b\) 的降序 排列;

所以我们可以得出一个结论:

\(a \le b\) 的部分尽量放在前面,然后按照 \(a\) 的升序排列,后面的部分显然就是 \(a>b\) 的部分,按照 \(b\) 的降序排列

于是,可以得出代码:

#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
struct Node {
	ll a, b, t;
	bool operator<(const Node& n2)const {
		if (t != n2.t)
		{
			return t < n2.t;
		}
		if (t != 3) { 
			return a < n2.a; 
		}
		else
		{
			return b > n2.b;
		}
	}
}node[100005];
//这里可以对比国王游戏的代码部分
int main() {
	int T, n;
	cin >> T;
	while (T--)
	{
		cin >> n;
		for (int i = 1; i <= n; i++) {
			cin >> node[i].a >> node[i].b;
			if (node[i].a < node[i].b) {
				//a[i]<b[i]的情况:
				node[i].t = 1;
			}
			else if (node[i].a == node[i].b) {
				//a[i]=b[i]的情况:
				node[i].t = 2;
			}
			else {
				node[i].t = 3;
			}
		}
		sort(node + 1, node + 1 + n);
		ll x, y;
		x = node[1].a, y = node[1].a + node[1].b;//开始第一个人的钱数
		for (int i = 2; i <= n; i++) {
			x += node[i].a;
			y = max(y, x) + node[i].b;
		}
		cout << y << endl;
	}
	return 0;
}

代码没啥好说的吧;

总结一下,这道题最难的地方是推柿子还有最后的证明过程,希望相邻两项比较的方法可以深入人心吧。

posted @ 2022-05-05 16:35  zsdqwq  阅读(55)  评论(0编辑  收藏  举报