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;
}