ZOJ4027 Sequence Swapping DP

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\n", ans);
    }
    return 0;
}
View Code

 

posted @ 2019-04-18 19:52  ckxkexing  阅读(151)  评论(0编辑  收藏  举报