這個題是一個國王遊戲的變形(國王遊戲就把我虐了qwq)
題目背景
還記得 NOIP 2012 提高組 Day1 的國王遊戲嗎?時光飛逝,光陰荏苒,兩年
過去了。國王遊戲早已過時,如今已被皇后遊戲取代,請你來解決類似於國王遊
戲的另一個問題。
題目描述
皇后有 n 位大臣,每位大臣的左右手上面分別寫上了一個正整數。恰逢國慶
節來臨,皇后決定爲 n 位大臣頒發獎金,其中第 i 位大臣所獲得的獎金數目爲第
i-1 位大臣所獲得獎金數目與前 i 位大臣左手上的數的和的較大值再加上第 i 位
大臣右手上的數。
形式化地講:我們設第 i 位大臣左手上的正整數爲 ai,右手上的正整數爲 bi,
則第 i 位大臣獲得的獎金數目爲 ci可以表達爲:
當然,吝嗇的皇后並不希望太多的獎金被髮給大臣,所以她想請你來重新安
排一下隊伍的順序,使得獲得獎金最多的大臣,所獲獎金數目儘可能的少。
注意:重新安排隊伍並不意味着一定要打亂順序,我們允許不改變任何一
位大臣的位置。
輸入輸出格式
輸入格式:
第一行包含一個正整數 T,表示測試數據的組數。
接下來 T 個部分,每個部分的第一行包含一個正整數 n,表示大臣的數目。
每個部分接下來 n 行中,每行兩個正整數,分別爲 ai和 bi,含義如上文所述。
輸出格式:
共 T 行,每行包含一個整數,表示獲得獎金最多的大臣所獲得的獎金數目
輸入輸出樣例:
輸入
1 3 4 1 2 2 1 2
輸出
8
分析
這道題貪心做法的正確性顯然,只需要將題目所給你的式子算的過程中加一個貪心排序就可以做了。
(國王遊戲要高精,但這個題我貌似long long水過了?!)
Codes:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #define ll long long using namespace std; ll n,T,sum; ll C[100866]; struct Node { int left; int right; bool operator < (const Node &rt) const { return min(left,rt.right) < min(right,rt.left); //重載運算符,注意這裏是用min的 } }node[100866]; inline int read() //快讀 { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch == '-') f = -1; ch=getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int main() { T = read(); //輸入數據組數 while(T--) { memset(C,0,sizeof(C)); //清空數組 n = read(); for(int i=1;i<=n;i++) { node[i].left = read(); node[i].right = read(); } sort(node + 1,node + n + 1); //已經重置好了,直接判斷就行 sum = 0; //別忘了要重置 for(int i=1;i<=n;i++) { sum += node[i].left; //以中間變量sum來存儲一個運算時候的變量,也保證了時時更新 C[i] = max(C[i - 1],sum) + node[i].right; //題目所描述的 } printf("%lld\n",C[n]); //輸出 } return 0; }
完結撒花qwq