[NOIP2012]國王遊戲 -高精度-貪心-
描述
恰逢 H 國國慶,國王邀請 n 位大臣來玩一個有獎遊戲。首先,他讓每個大臣在左、右手上面分別寫下一個整數,國王自己也在左、右手上各寫一個整數。然後,讓這 n 位大臣排成一排,國王站在隊伍的最前面。排好隊後,所有的大臣都會獲得國王獎賞的若干金幣,每位大臣獲得的金幣數分別是:排在該大臣前面的所有人的左手上的數的乘積除以他自己右手上的數,然後向下取整得到的結果。
國王不希望某一個大臣獲得特別多的獎賞,所以他想請你幫他重新安排一下隊伍的順序,使得獲得獎賞最多的大臣,所獲獎賞儘可能的少。注意,國王的位置始終在隊伍的最前面。
Solution
貪心。左手的數用\(l[i]\)表示,右手的數用\(r[i]\)
但是為什麼呢?
可以考慮相鄰的兩個大臣\(a_i和a_{i+1}\),他們的獎賞分別為(左邊為\(a_i\),右邊為\(a_{i+1}\))
\(\frac{1}{r[i]}*\prod_{k=0}^{i-1}l[k]和\frac{1}{r[i+1]}*\prod_{k=0}^{i}l[k]\)
交換位置後他們的獎賞為
\(\frac{l[i + 1]}{r[i]}*\prod_{k=0}^{i-1}l[k]和\frac{1}{r[i+1]}*\prod_{k=0}^{i-1}l[k]\)
然後我們來比較
\(max(\frac{1}{r[i+1]}*\prod_{k=0}^{i-1}l[k],\frac{l[i]}{r[i]}*\prod_{k=0}^{i-1}l[k])和max(\frac{1}{r[i]}*\prod_{k=0}^{i-1}l[k],\frac{1}{r[i+1]}*\prod_{k=0}^{i}l[k])\)
同乘\(\frac{1}{r[i+1]*r[i]}*\prod_{k=0}^{i-1}l[k]\)
即比較
\(\\max(r[i + 1],l[i]*r[i])................1\\max(r[i],r[i+1]*l[i+1])...............2\)
\(\\r[i+1] < r[i + 1]*l[i + 1]且r[i] < r[i] * l[i]\)
當\(l[i]*r[i] < l[i+1]*r[i+1]\)時,\(1\)式小於\(2\)式,交換前更優,即把\(l[i]*r[i]\)小的放在前面更優。
#include<bits/stdc++.h>
using namespace std;
const int MOD = 10000;
struct bint{
int a[5000], len;
int& operator [] (int x) { return a[x]; }
bint():len(1){ memset(a, 0, sizeof(a));}
bint(long long x) { memset(a, 0, sizeof(a)); len = 0; while(x) { a[++len] = x % MOD; x /= MOD; } }
void print(){
printf("%d", a[len]);
for (int i = len - 1; i > 0; i--)
printf("%04d", a[i]);
}
};
bint operator * (bint& a,int b){
int x = 0;
for (int i = 1; i <= a.len; i++)
x += a[i] * b, a[i] = x % MOD, x /= MOD;
if(x) a[++a.len] = x;
return a;
}
bint operator / (bint& a,int b){
bint c; c.len = a.len; int x = 0;
for (int i = a.len; i > 0; i--) {
x = x * MOD + a[i];
c[i] = x / b;
x %= b;
}
while(c[c.len] == 0 && c.len > 1) c.len--;
return c;
}
bool operator < (bint& a,bint & b){
if(a.len > b.len) return false;
if(a.len < b.len) return true;
for(int i = a.len; i >= 0; i--){
if(a[i] < b[i]) return true;
if(a[i] > b[i]) return false;
}
return false;
}
struct obj{
int l, r, lr;
}a[1010];
bool cmp(obj a,obj b){
return a.lr < b.lr;
}
int n;
int main(){
cin >> n;
for (int i = 0; i <= n; i++){
cin >> a[i].l >> a[i].r;
a[i].lr = a[i].l * a[i].r;
}
sort(a + 1, a + n + 1, cmp);
bint s(1),ans;
for (int i = 1; i <= n; i++){
if(a[i - 1].l == 0) break;
s = s * a[i - 1].l;
bint tmp;
tmp = s / a[i].r;
if(ans < tmp){
ans = tmp;
}
}
ans.print();
}