CF 1443D Extreme Subtraction(貪心,構造)

傳送門

 

 

 

樣例(x):

8

15 16 17 19 27 36 29 33

結果(t1)

15 15 16 18 26 35 28 32

思路:我們可以把最左端和最右端當做兩個水龍頭,每個水龍頭流量的上限就是a[x].

我們通過貪心,我們儘可能的使用左邊的流量,例如樣例(x),我們流到第二個點的時候,我們發現左邊的流量不可能在第二個點流出16單位流量,說明這個點需要右邊流量的補充,而且只需要補充1單位的流量,那有人會問,為什麼不多流過來一些呢,這裡就是貪心的想法,我左邊邊能完成的事就不勞煩你右邊,儘可能的使用左邊,不行的讓右邊來補充,這樣樣例(x)的數組就變成了結果(t1)的數組,當然,我們需要更新左邊能流過來的流量flow = min(flow, a[i])和記錄我們右邊已經流向左邊的流量d,因為右邊流過來了流量,那麼右邊的容量也就是剩餘還需要補充的流量需要減少,當我們繼續流向下一個點的時候,當前需要流過來的流量應該是a[now] -= d,d為右邊流過來的流量,如果a[now] < 0,說明這個點不能夠承載d的流量,否則繼續進行更新操作。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <queue>
 5  
 6 using namespace std;
 7  
 8 #define ll long long
 9 #define pb push_back
10 #define lson(rt) (rt << 1)
11 #define rson(rt) (rt << 1 | 1)
12 #define fi first
13 #define se second
14  
15 const int N  = 3e4 + 10;
16 int a[N];
17  
18 void solve()
19 {
20     int _case = 0;
21     scanf("%d", &_case);
22     for(int o = 1; o <= _case; ++o) {
23         int n;
24         scanf("%d", &n);
25         for(int i = 1; i <= n; ++i) scanf("%d", a + i);
26         
27         int flag = 1;
28         int d = 0;
29         int Min = a[1];
30         for(int i = 2; i <= n; ++i) {
31             a[i] -= d;
32             if(a[i] < 0) flag = 0;
33             if(Min >= a[i]) Min = a[i];
34             else {
35                 d += a[i] - Min;
36             }
37         }
38         //for(int i = 1; i <= n; ++i) cout << a[i] << " ";
39         //cout << endl;
40  
41         printf("%s\n", flag ? "YES" : "NO");
42     }
43 }
44  
45 int main(){
46  
47     solve();
48  
49     return 0;
50 }/*
51 8
52  15 16 17 19 27 36 29 33
53  */

 

Tags: