link:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4027
题意:
有一个括号序列,每个括号对应一个值,现在可以使得相邻的()进行交换,并得到两个值的乘积,问最后能得到的最大值。
思路:
从后向前考虑,取后缀最大值。
#include <bits/stdc++.h> using namespace std; #define pb push_back #define fi first #define se second typedef long long ll; typedef pair<int, int> pii; const int inf = 0x3f3f3f3f; const int maxn = 1e3+9; char str[maxn]; ll dp[maxn],mul[maxn],a[maxn]; int main(){ int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); scanf("%s", str+1); for(int i=1; i<=n; i++) scanf("%lld", &a[i]); for(int i=1; i<=n; i++) dp[i] = 0; ll ans = 0; for(int i=n; i>=1; i--) { if(str[i] == '(') { ll sum = 0; for(int j=1; j<=n; j++) mul[j] = 0; for(int j=i; j<=n; j++) { if(str[j] == ')')sum += a[i] * a[j]; mul[j] = sum; } ll mx = -2e18; for(int j=n; j>0; j--) { mx = max(mx, dp[j]); dp[j] = mx + mul[j]; ans = max(ans, dp[j]); } } } printf("%lld ", ans); } return 0; }