1. 程式人生 > >[貪心]任務執行順序

[貪心]任務執行順序

div 存儲 printf sum cmp .com color course str

https://www.51nod.com/tutorial/course.html#!courseId=23

題目大意:有$N$個任務需要執行,第$i$個任務計算時占$R[i]$個空間,而後會釋放一部分,最後儲存計算結果需要占據$O[i]$個空間$(O[i] < R[i])$。

例如:執行需要$5$個空間,最後儲存需要$2$個空間。給出$N$個任務執行和存儲所需的空間,問執行所有任務最少需要多少空間。

解題關鍵:按照$b[i]$不增的順序排序,是最“有利”的。

一定註意:輸入的不是a,b,而是O與R,比較的是b,兩者的差的絕對值

結論:

如果對於$b[0] > = b[1] > = \ldots > = b[x] < b[x + 1]$

$\left( {a[0],b[0]} \right) \ldots .\left( {a[x],{\rm{ }}b[x]} \right){\rm{ }}\left( {a[x + 1],{\rm{ }}b[x + 1]} \right)$的組合可以不產生負數,則我們交換$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不增順序排序的序列執行的方案,從而證明了我們的貪心策略是有效的。

 1 #include<bits/stdc++.h>
 2
using namespace std; 3 typedef long long ll; 4 struct node{ 5 int a,b; 6 }c[100002]; 7 bool cmp(node x,node y){ 8 return x.a-x.b>y.a-y.b; 9 } 10 int main(){ 11 int n; 12 cin>>n; 13 for(int i=0;i<n;i++) cin>>c[i].a>>c[i].b; 14 sort(c,c+n,cmp); 15 int sum=c[0].a,tt=0; 16 for(int i=0;i<n;i++){ 17 if(tt+c[i].a>sum) sum=tt+c[i].a; 18 tt+=c[i].b; 19 } 20 printf("%d",sum); 21 return 0; 22 }

[貪心]任務執行順序