1. 程式人生 > 其它 >洛谷 P1080 [NOIP2012 提高組] 國王遊戲

洛谷 P1080 [NOIP2012 提高組] 國王遊戲

Descrption

洛谷傳送門

Solution

一道非常好的貪心題。

我們只考慮國王以及兩個大臣,編號依次為 1,2,3

左手分別寫著 \(a_1\)\(a_2\)\(a_3\),右手上分別寫著 \(b_1\)\(b_2\)\(b_3\)

對於 2 在前還是 3 在前分別考慮:

  • 1 - 2 - 3:

這種情況下: $$ans_1 = max(\frac{a_1}{b_2}, \frac{a_1 * a_2}{b_3})$$

  • 1 - 3 - 2:

此時:$$ans_2 = max(\frac{a_1}{b_3}, \frac{a_1 * a_3}{b2})$$

代換一下可得:

\[ans_1 = max(k_1, k_2) \]\[ans_2 = max(k_3, k_4) \]

容易發現,\(k_2 \geq k_3\)\(k_4 \geq k_1\)

\(ans_1 < ans_2\),那麼 \(k_2 < k_4\)

即:$$\frac{a_1 * a_2}{b_3} < \frac{a_1 * a_3}{b_2}$$

兩邊同乘 \(b_2 * b_3\),然後同時除以 \(a_1\) 可得:$$a_2 * b_2 < a_3 * b_3$$

然後就很簡單了,直接對於輸入的大臣,按照 \(a_i * b_i\) 排序即可。

注意要用高精度

這個才是難點)。

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 1010

using namespace std;


inline int read(){
	int x = 0;
	char ch = getchar();
	while (ch < '0' && ch > '9') ch = getchar();
	while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
	return x;
}

struct node{
	int num[100000];
	node(){
		memset(num, 0, sizeof(num));
	}
	bool operator > (const node &b) const{
		if(num[0] > b.num[0]) return 1;
		if(num[0] < b.num[0]) return 0;
		for(int i = num[0]; i >= 1; i--){
			if(num[i] > b.num[i]) return 1;
			if(num[i] < b.num[i]) return 0;
		}
		return 0;
	}
	node operator + (const node &b) const{
		node c;
		c.num[0] = min(100, max(num[0], b.num[0]));
		for(int i = 1; i <= c.num[0]; i++)
			c.num[i] = num[i] + b.num[i];
		for(int i = 1; i <= c.num[0]; i++){
			c.num[i + 1] += c.num[i] / 10;
			c.num[i] %= 10;
		}
		if(c.num[c.num[0] + 1]) c.num[0]++;
		return c;
	}
	node operator * (int b) const{
		node c;
		int w = 0;
		c.num[0] = num[0];
		for(int i = 1; i <= c.num[0]; i++){
			c.num[i] = num[i] * b + w;
			w = c.num[i] / 10;
			c.num[i] %= 10;
		}
		if(w) c.num[++c.num[0]] = w;
		while(c.num[c.num[0]] >= 10){
			c.num[c.num[0] + 1] = c.num[c.num[0]] / 10;
			c.num[c.num[0]++] %= 10;
		}
		return c;
	}
	node operator / (const int b) const{
		node c;
		int w = 0;
		for(int i = num[0]; i >= 1; i--){
			w = w * 10 + num[i];
			c.num[i] = w / b;
			w %= b;
		}
		c.num[0] = num[0];
		while(!c.num[c.num[0]] && c.num[0] > 1) c.num[0]--;
		return c;
	}
}ans, tmp, maxs, A;
int B;
struct people{
	int a,b,val;
	bool operator < (const people &b){
		return val < b.val;
	}
}p[N];
int n;

int main(){
	ios :: sync_with_stdio(false);
	cin >> n >> p[1].a >> p[1].b;
	p[1].val = p[1].a * p[1].b;
	for(int i = 2; i <= n + 1; i++){
		cin >> p[i].a >> p[i].b;
		p[i].val = p[i].a * p[i].b;
	}
	sort(p + 2, p + 2 + n);
	ans.num[0] = ans.num[1] = 1;
	for(int i = 2; i <= n + 1; i++){
		ans = ans * p[i - 1].a;
		tmp = ans / p[i].b;
		if(tmp > maxs)
			memcpy(maxs.num, tmp.num, sizeof(tmp.num));
	}
	for(int i = maxs.num[0]; i >= 1; i--)
		cout << maxs.num[i];
	cout << endl;
	return 0;
}

End

本文來自部落格園,作者:{xixike},轉載請註明原文連結:https://www.cnblogs.com/xixike/p/15376899.html