1. 程式人生 > 其它 >動態規劃:Educational Codeforces Round 123 (Rated for Div. 2)C. Increase Subarray Sums (最大連續區間和)

動態規劃:Educational Codeforces Round 123 (Rated for Div. 2)C. Increase Subarray Sums (最大連續區間和)

C. Increase Subarray Sums

傳送門:Problem - 1644C - Codeforces

 

 

 

  題目大意就是:給你一個序列,算出序列和為sum,求是否有連續區間和大於等於sum,有就輸出NO,否則YES,並且連續區間不能是[1,n],也就是整個序列,我的思路就是構建兩個DP陣列,既然區間不能是1->n,那麼一個dp從1->n-1,第二個從2->n,求dp[i],i代表以i結尾的區間的最大連續區間和,有大於等於sum的直接輸出NO,最後都沒有的話就輸出YES。本質上就是一個最大連續區間和的問題。

  上程式碼:

 1 #include<iostream>
 2
#include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<map> 6 using namespace std; 7 const int maxn = 1e5 + 5; 8 const int inf = -0x7FFFFFFF; 9 long long a[maxn]; 10 long long dp1[maxn]; 11 long long dp2[maxn]; 12 long long read() 13 { 14 long long x = 0
, f = 1; 15 char ch = getchar(); 16 if (ch > '9' || ch < '0') 17 { 18 f = -1; 19 ch = getchar(); 20 } 21 while (ch >= '0' && ch <= '9') 22 { 23 x = (x << 3) + (x << 1) + ch -'0'; 24 ch = getchar(); 25 } 26 return
x * f; 27 } 28 long long max(long long a, long long b) 29 { 30 if (a > b) 31 return a; 32 else return b; 33 } 34 int main() 35 { 36 long long t; 37 t = read(); 38 while (t--) 39 { 40 long long n; 41 n = read(); 42 long long sum = 0; 43 for (int i = 0; i <= n; ++i)dp1[i] = inf, dp2[i] = inf; 44 for (int i = 1; i <= n; ++i) 45 { 46 a[i] = read(); 47 sum += a[i]; 48 } 49 bool flag = 0; 50 for (int i = 1; i < n; ++i) 51 { 52 dp1[i] = max(dp1[i - 1], 0) + a[i]; 53 if (dp1[i] >= sum) 54 { 55 flag = 1; 56 break; 57 } 58 59 } 60 if (!flag) 61 { 62 for (int i = 2; i <= n; ++i) 63 { 64 dp2[i] = max(dp2[i - 1], 0) + a[i]; 65 if (dp2[i] >= sum) 66 { 67 flag = 1; 68 break; 69 } 70 } 71 } 72 if (flag)cout << "NO"<<endl; 73 else cout << "YES"<<endl; 74 75 } 76 return 0; 77 78 }

0X7FFFFFFF代表INT最小的。挺好用的,一般定義為inf。