傳送門ios
題目:給定長度爲n的數組,下標從0開始。你能夠至多翻轉一次連續的子數組,問a0 + a2 + ... + a2k最大是多少。數組
思路:咱們發現一個狀況: 20 30 10 ...,咱們發現若是30和20反轉也能夠和後面10的的反轉,就分紅了兩種狀況,咱們能夠經過dp來解決,當前這個數與左邊一塊兒反轉差值仍是與右邊一塊兒反轉翻轉差值大。spa
初始化dp[0~n] = 0,咱們把下標改爲從1開始,則變成a1 + a3 + a5 + ... + a2k-1。code
①i & 1 : dp[i] = max(dp[i], dp[i - 2] + a[i - 1] - a[i]blog
②!(i&1): dp[i] = max(dp[i], dp[i - 2] + a[i] - a[i - 1)ci
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <queue> 5 #include <string> 6 #include <vector> 7 #include <cmath> 8 9 using namespace std; 10 11 #define ll long long 12 #define pb push_back 13 #define fi first 14 #define se second 15 16 const int N = 2e5 + 10; 17 ll a[N], dp[N], sum; 18 19 void solve() 20 { 21 int T; 22 cin >> T; 23 while(T--){ 24 int n; 25 cin >> n; 26 27 sum = 0; 28 for(int i = 1; i <= n; ++i){ 29 cin >> a[i]; 30 if(i & 1) sum += a[i]; 31 } 32 for(int i = 1; i <= n; ++i) dp[i] = 0; 33 34 for(int i = 2; i <= n; ++i){ 35 if(i & 1){ 36 dp[i] = max(dp[i], dp[i - 2] + a[i - 1] - a[i]); 37 }else{ 38 dp[i] = max(dp[i], dp[i - 2] + a[i] - a[i - 1]); 39 } 40 } 41 42 ll max_d = 0; 43 for(int i = 0; i <= n; ++i) max_d = max(max_d, dp[i]); 44 //cout << "max = "; 45 cout << sum + max_d << endl; 46 } 47 } 48 49 int main() 50 { 51 ios::sync_with_stdio(false); 52 cin.tie(0); 53 cout.tie(0); 54 solve(); 55 56 return 0; 57 }