P4342

P4342

考虑 区间DP

这题的符号既有加号又有乘号,那么就不能简单只维护,([l,r]) 区间的最大值。比如负数和负数相乘就变成整数比维护的最大值还要大这种情况。

所以我们维护两个值:(dp_{max}[l][r],dp_{min}[l][r])

分开计算:

(op == t) : (dp_{max}[l][r] = max(dp_{max}[l][k]+dp_{max}[k + 1][r]),dp_{min}[l][r] = min(dp_{min}[l][k] + dp_{min}[k + 1][r]))

(op == x):(dp_{max}[l][r] = max(dp_{max}[l][k] imes dp_{max}[k + 1][r],dp_{min}[l][k] imes dp_{min}[k + 1][r],dp_{min}[l][k] imes dp_{max}[k + 1][r],dp_{max}[l][k] imes dp_{min}[k + 1][r])) (dp_{min}[l][r] = min(dp_{min}[l][k] imes dp_{min}[k + 1][r],dp_{min}[l][k] imes dp_{min}[k + 1][r],dp_{min}[l][k] imes dp_{max}[k + 1][r],dp_{max}[l][k] imes dp_{min}[k + 1][r]))) 其实主要是考虑 相乘或相加的两个数大于 (0) 或者小于 (0)

#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define rep(I, N) for (int I = 1; I <= (N); ++I)
#define repp(I, N) for (int I = 0; I < (N); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORR(I, A, B) for (int I = (A); I >= (B); I--)
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
const int N = 300 + 5;
const double eps = 1e-7;
const int mod = 1e9 + 7;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
LL gcd(LL a,LL b){return b>0?gcd(b,a%b):a;}
LL ksm(LL a,LL b){LL ans = 1;while(b){if(b&1) ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans % mod;}
map<PII, char> mp;
LL dp_max[N][N];
LL dp_min[N][N];
LL a[N];
char b[N];
int totb = 0;
int main() {
    int n;
    cin >> n;
    int tot = 0;
    rep(i,2 * n)
    {
        if(i % 2)
        {
            string s;
            cin >> s;
            b[++totb] = s[0];
        }
        else 
        {
            int x;
            cin >> x;
            a[++tot] = x;
        }
    }
    memset(dp_max,0xcf,sizeof dp_max);
    memset(dp_min, 0x3f, sizeof dp_min);
    rep(i,tot)
    {
        a[i + tot] = a[i];
        b[i + totb] = b[i];
    }
    rep(i,tot * 2) 
    {
        dp_max[i][i] = a[i];
        dp_min[i][i] = a[i];
    }
    FOR(len,2,tot * 2)
    {
        rep(l,tot * 2 - len + 1)
        {
            int r = l + len - 1;
            FOR(k,l,r - 1)
            {
                if(b[k + 1] == 't')
                {
                    LL &ans = dp_max[l][r];
                    ans = max(ans,dp_max[l][k] + dp_max[k + 1][r]);
                    LL &t = dp_min[l][r];
                    t = min(t, dp_min[l][k] + dp_min[k + 1][r]);
                }
                else 
                {
                    LL &ans = dp_max[l][r];
                    ans = max(ans, dp_max[l][k] * dp_max[k + 1][r]);
                    ans = max(ans, dp_min[l][k] * dp_min[k + 1][r]);
                    ans = max(ans, dp_max[l][k] * dp_min[k + 1][r]);
                    ans = max(ans, dp_min[l][k] * dp_max[k + 1][r]);
                    LL &t = dp_min[l][r];
                    t = min(t,dp_min[l][k] * dp_min[k + 1][r]);
                    t = min(t,dp_max[l][k] * dp_max[k + 1][r]);
                    t = min(t,dp_max[l][k] * dp_min[k + 1][r]);
                    t = min(t, dp_min[l][k] * dp_max[k + 1][r]);
                } 
            }
        }
    }
    LL ans = 0;
    vector<int> v;
    rep(i,tot)
    {
        ans = max(ans, dp_max[i][i + n - 1]);
    }
    rep(i,tot)
    {
        if(dp_max[i][i + n - 1] == ans)
            v.push_back(i);
    }
    cout << ans << endl;
    for (int i = 0;i < v.size();i++) cout << v[i] << ' ';
    cout << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/strategist-614/p/12539413.html