有n個任務需要執行,第i個任務計算時佔r[i]個空間,而後會釋放一部分,最後儲存計算結果需要佔據o[i]個空間(o[i] < r[i])。例如:執行需要5個空間,最後儲存需要2個空間。給出n個任務執行和儲存所需的空間,問執行所有任務最少需要多少空間。
輸入第1行:1個數n,表示任務的數量。(2 <= n <= 100000)輸出第2 - n + 1行:每行2個數r[i]和o[i],分別為執行所需的空間和儲存所需的空間。(1 <= o[i] < r[i] <= 10000)
輸出執行所有任務所需要的最少空間。
輸入示例解題思路:貪心,設b=r-o;按照b從大到小的順序進項排序,如果b相同,按照o從大到小的順序進行排序,2014 1
2 111 3
20 4
7 56 5
20 7
19 8
9 420 10
18 11
12 6
13 12
14 9
15 2
16 15
17 15
19 13
20 2
20 1
輸出示例
135
本題可以抽象成,從乙個整數開始,每次減去a,再加上b (a,b都是正數),要求每次操作都不產生負數。
針對本題a[i] = r[i], b[i] = r[i] – o[i],注意o[i] < r[i],我們有0
我們給出標準答案——按照b[i]不增的順序排序,是最「有利」的。
為了定義「有利」,我們這樣證明我們的結論:
如果對於b[0]>=b[1] >=…>=b[x] < b[x + 1]
(a[0],b[0])….(a[x], b[x]) (a[x + 1], b[x + 1])的組合可以不產生負數,則我們交換b[x]和b[x + 1]也可以不產生負數。
證明:交換(a[x], b[x])和(a[x + 1], b[x + 1])對x + 1更有利了,因為每個括號實際上是乙個負數,所以越早安排這個括號,被減數就越大,就越不容易形成負數。
關鍵看(a[x],b[x])移動到後面會不會產生負數。
那其實是看之前的結果 -a[x + 1] + b[x + 1] – a[x]會不會產生負數,(注意-a[x + 1] + b[x + 1]不會產生負數,因為我們剛才已經證明了,對x + 1更有利)
而我們知道之前的結果-a[x] + b[x] – a[x + 1]不會產生負數(因為我們的假設就是這樣),而b[x + 1] > b[x],所以前者更大,所以-a[x + 1] + b[x + 1] – a[x]不會產生負數。
因此我們證明了交換之後仍然不產生負數,也就是原先不產生負數,我們交換後仍然不產生負數。
而經過若干次這樣的交換之後,我們肯定會把序列交換成按照b的不增順序排序的。從而我們證明了,任何可行的方案都不好於按照b不增順序排序的序列執行的方案,從而證明了我們的貪心策略是有效的。
ac**:
#include#includeusing namespace std;
const int maxn=1e5+10;
struct nodea[maxn];
bool cmp(node a,node b)
int main()
sort(a,a+n,cmp);
int ans=a[0].r,x=a[0].b;//ans為所求結果,x為當前剩餘空間
for(int i=1;ielse//剩餘時間足夠不需要更新ans,只需更新剩餘時間即可
x=x-a[i].o;
} cout<}
51NOD 任務執行順序
有n個任務需要執行,第i個任務計算時佔r i 個空間,而後會釋放一部分,最後儲存計算結果需要佔據o i 個空間 o i r i 例如 執行需要5個空間,最後儲存需要2個空間。給出n個任務執行和儲存所需的空間,問執行所有任務最少需要多少空間。思路 這是乙個貪心演算法,依據執行空間 儲存空間的大小排序即...
51NOD貪心教程(任務執行順序典型題 詳細解析)
有n個任務需要執行,第i個任務計算時佔r i 個空間,而後會釋放一部分,最後儲存計算結果需要佔據o i 個空間 o i r i 例如 執行需要5個空間,最後儲存需要2個空間。給出n個任務執行和儲存所需的空間,問執行所有任務最少需要多少空間。分析 本題可以抽象成,從乙個整數開始,每次減去a,再加上b ...
51NOD 1099 任務執行順序
1099 任務執行順序 基準時間限制 1 秒 空間限制 131072 kb 分值 20 難度 3級演算法題 有n個任務需要執行,第i個任務計算時佔r i 個空間,而後會釋放一部分,最後儲存計算結果需要佔據o i 個空間 o i r i 例如 執行需要5個空間,最後儲存需要2個空間。給出n個任務執行和...