题意:给你一个序列 这个序列代表是 a[1] - a[2] - ......-a[n] ,然后每一次更改其中的一个值,你只能在这个算式中最多加两个括号,问你使得这个算式得到的最大值是多少。
解题思路:
1)因为最多加两个括号 ,我们可以知道括号嵌套会负负得正所以相当于两个没有交集的括号,这里我们又想到连续字串和,但是字串和又可以嵌套,那怎么办,
就正序求一遍,逆序再求一遍。
解题代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "SuccessiveSubtraction2.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <string> 15 #include <iostream> 16 #include <sstream> 17 #include <map> 18 #include <set> 19 #include <queue> 20 #include <stack> 21 #include <fstream> 22 #include <numeric> 23 #include <iomanip> 24 #include <bitset> 25 #include <list> 26 #include <stdexcept> 27 #include <functional> 28 #include <utility> 29 #include <ctime> 30 using namespace std; 31 32 #define PB push_back 33 #define MP make_pair 34 35 #define REP(i,n) for(i=0;i<(n);++i) 36 #define FOR(i,l,h) for(i=(l);i<=(h);++i) 37 #define FORD(i,h,l) for(i=(h);i>=(l);--i) 38 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long LL; 43 typedef pair<int,int> PII; 44 #define maxn 2005 45 int ary[maxn]; 46 int n; 47 int dpz[maxn]; 48 int dpf[maxn]; 49 int solve() 50 { 51 memset(dpz,0,sizeof(dpz)); 52 memset(dpf,0,sizeof(dpf)); 53 int tsum = 0 ; 54 // for(int i = 1 ;i <= n;i ++) 55 // printf("%d ",ary[i]); 56 // printf("\n"); 57 for(int i = 3;i <= n;i ++) 58 { 59 if(tsum < 0 ) 60 tsum =0 ; 61 tsum += ary[i]; 62 dpz[i] = max(dpz[i],tsum); 63 } 64 tsum = 0 ; 65 int ans = 0 ; 66 for(int i = n;i >= 3 ;i --) 67 { 68 if(tsum < 0 ) 69 tsum =0 ; 70 tsum += ary[i]; 71 dpf[i] = max(dpf[i+1],tsum); 72 ans = max(dpf[i] + dpz[i-2],ans); 73 } 74 return ans ; 75 } 76 class SuccessiveSubtraction2 77 { 78 public: 79 vector <int> calc(vector <int> a, vector <int> p, vector <int> v) 80 { 81 vector<int> ans ; 82 n = a.size(); 83 int sum =0 ; 84 for(int i =0 ;i < n ;i ++) 85 { 86 ary[i+1] =a[i]; 87 } 88 int k = p.size(); 89 for(int i =0 ;i < k ;i ++) 90 { 91 ary[p[i]+1] = v[i]; 92 sum = ary[1] *2; 93 for(int j = 1;j <= n;j ++) 94 sum -= ary[j]; 95 //printf("%d ",sum); 96 sum += solve()*2; 97 //printf("%d\n",solve()); 98 ans.push_back(sum); 99 } 100 return ans ; 101 } 102 103 // BEGIN CUT HERE 104 public: 105 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); } 106 private: 107 template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 108 void verify_case(int Case, const vector <int> &Expected, const vector <int> &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: " << print_array(Expected) << endl; cerr << "\tReceived: " << print_array(Received) << endl; } } 109 void test_case_0() { int Arr0[] = {1, 2, 3, 4, 5}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {1, 2, 0, 4, 3}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {3, 9, -10, 5, 1}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {10, 16, 5, 5, 2 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(0, Arg3, calc(Arg0, Arg1, Arg2)); } 110 void test_case_1() { int Arr0[] = {-100, -100, -100, -100, -100}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 1, 2, 3, 4}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0, 0, 0, 0, 0}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {400, 300, 200, 100, 0 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(1, Arg3, calc(Arg0, Arg1, Arg2)); } 111 void test_case_2() { int Arr0[] = {83, 0, 25, 21}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 3, 2, 1, 3, 1, 2}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {10, -90, 33, 52, -100, 0, 45}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {56, 125, 133, 81, 91, 143, 155 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(2, Arg3, calc(Arg0, Arg1, Arg2)); } 112 void test_case_3() { int Arr0[] = {1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 0, 0, 0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {10, -10, 100, -100}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {10, -10, 100, -100 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(3, Arg3, calc(Arg0, Arg1, Arg2)); } 113 void test_case_4() { int Arr0[] = {-11, -4, 28, 38, 21, -29, -45, 11, -58, -39, 92, 35, -56, -6, 29, -2, 61, 10, -29, -63}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {19, 5, 3, 10, 4, 18, 5, 2, 0, 15}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {-19, 21, 7, -66, 38, -39, -22, 24, -32, 13}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {451, 443, 412, 440, 457, 467, 468, 464, 443, 458 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(4, Arg3, calc(Arg0, Arg1, Arg2)); } 114 115 // END CUT HERE 116 117 }; 118 119 // BEGIN CUT HERE 120 int main() 121 { 122 SuccessiveSubtraction2 ___test; 123 ___test.run_test(-1); 124 return 0; 125 } 126 // END CUT HERE
2)分段dp, dp[i][0-4] 表示 i处于 (第一段 第一个空格内 两个空格间隙 第二个空格内 最后一段) 这五种状态
解题代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "SuccessiveSubtraction2.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <string> 15 #include <iostream> 16 #include <sstream> 17 #include <map> 18 #include <set> 19 #include <queue> 20 #include <stack> 21 #include <fstream> 22 #include <numeric> 23 #include <iomanip> 24 #include <bitset> 25 #include <list> 26 #include <stdexcept> 27 #include <functional> 28 #include <utility> 29 #include <ctime> 30 using namespace std; 31 32 #define PB push_back 33 #define MP make_pair 34 35 #define REP(i,n) for(i=0;i<(n);++i) 36 #define FOR(i,l,h) for(i=(l);i<=(h);++i) 37 #define FORD(i,h,l) for(i=(h);i>=(l);--i) 38 39 typedef vector<int> VI; 40 typedef vector<string> VS; 41 typedef vector<double> VD; 42 typedef long long LL; 43 typedef pair<int,int> PII; 44 #define maxn 2005 45 int ary[maxn]; 46 int n; 47 int dp[maxn][6]; 48 int solve() 49 { 50 int ans = -1e9; 51 memset(dp,0,sizeof(dp)); 52 for(int i = 1;i <= n;i ++) 53 for(int j = 0 ;j <= 4; j ++) 54 dp[i][j] = -1e9; 55 dp[1][0] = ary[1]; 56 dp[2][0] = ary[1]-ary[2]; 57 for(int i = 3 ;i <= n;i ++) 58 { 59 dp[i][0] = dp[i-1][0] - ary[i] ; 60 dp[i][1] = max(dp[i-1][1]+ary[i],dp[i-1][0]+ary[i]); 61 dp[i][2] = max(dp[i-1][2]-ary[i],dp[i-1][1]-ary[i]); 62 dp[i][3] = max(dp[i-1][3]+ary[i],dp[i-1][2]+ary[i]); 63 dp[i][4] = max(dp[i-1][4]-ary[i],dp[i-1][3]-ary[i]); 64 } 65 for(int i= 0 ;i <= 4;i ++) 66 { 67 ans = max(ans,dp[n][i]) ; 68 } 69 return ans ; 70 } 71 class SuccessiveSubtraction2 72 { 73 public: 74 vector <int> calc(vector <int> a, vector <int> p, vector <int> v) 75 { 76 vector<int> ans ; 77 n = a.size(); 78 int sum =0 ; 79 for(int i =0 ;i < n ;i ++) 80 { 81 ary[i+1] =a[i]; 82 } 83 int k = p.size(); 84 for(int i =0 ;i < k ;i ++) 85 { 86 ary[p[i]+1] = v[i]; 87 ans.push_back(solve()); 88 } 89 return ans ; 90 } 91 92 // BEGIN CUT HERE 93 public: 94 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); } 95 private: 96 template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 97 void verify_case(int Case, const vector <int> &Expected, const vector <int> &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: " << print_array(Expected) << endl; cerr << "\tReceived: " << print_array(Received) << endl; } } 98 void test_case_0() { int Arr0[] = {1, 2, 3, 4, 5}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {1, 2, 0, 4, 3}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {3, 9, -10, 5, 1}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {10, 16, 5, 5, 2 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(0, Arg3, calc(Arg0, Arg1, Arg2)); } 99 void test_case_1() { int Arr0[] = {-100, -100, -100, -100, -100}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 1, 2, 3, 4}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0, 0, 0, 0, 0}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {400, 300, 200, 100, 0 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(1, Arg3, calc(Arg0, Arg1, Arg2)); } 100 void test_case_2() { int Arr0[] = {83, 0, 25, 21}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 3, 2, 1, 3, 1, 2}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {10, -90, 33, 52, -100, 0, 45}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {56, 125, 133, 81, 91, 143, 155 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(2, Arg3, calc(Arg0, Arg1, Arg2)); } 101 void test_case_3() { int Arr0[] = {1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0, 0, 0, 0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {10, -10, 100, -100}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {10, -10, 100, -100 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(3, Arg3, calc(Arg0, Arg1, Arg2)); } 102 void test_case_4() { int Arr0[] = {-11, -4, 28, 38, 21, -29, -45, 11, -58, -39, 92, 35, -56, -6, 29, -2, 61, 10, -29, -63}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {19, 5, 3, 10, 4, 18, 5, 2, 0, 15}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {-19, 21, 7, -66, 38, -39, -22, 24, -32, 13}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {451, 443, 412, 440, 457, 467, 468, 464, 443, 458 }; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); verify_case(4, Arg3, calc(Arg0, Arg1, Arg2)); } 103 104 // END CUT HERE 105 106 }; 107 108 // BEGIN CUT HERE 109 int main() 110 { 111 SuccessiveSubtraction2 ___test; 112 ___test.run_test(-1); 113 return 0; 114 } 115 // END CUT HERE