P4342 [IOI1998]Polygon
Posted TURNINING
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4342 [IOI1998]Polygon相关的知识,希望对你有一定的参考价值。
思路:区间dp,套路很常见,需要注意一点的是*的情况,因为顶点的值有正有负所以可能出现两个负数相乘的值大于两正数相乘的值,故我们还得求一个去区间最小值。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100 + 10;
const LL INF = 1e17;
const int MAX_LOG_N = 20;
const double eps = 1e-6;
const int mod = 1e9 + 7;
int n;
LL v[maxn], f[maxn][maxn], g[maxn][maxn];
int op[maxn];
void solve() {
scanf("%d", &n);
for(int i = 1; i <= 2 * n; i++) {
for(int j = 1; j <= 2 * n; j++) {
f[i][j] = -INF;
g[i][j] = INF;
}
}
for(int i = 1; i <= n; i++) {
char s[2];
scanf("%s %lld", s, &v[i]);
if(*s == 't') op[i] = 1;
else op[i] = -1;
f[i][i] = f[i+n][i+n] = v[i];
g[i][i] = g[i+n][i+n] = v[i];
op[i+n] = op[i];
}
for(int len = 2; len <= n; len++) {
for(int i = 1; i + len - 1 <= 2 * n; i++) {
int j = i + len - 1;
for(int k = i; k + 1 <= j; k++) {
if(op[k+1] == 1) {
f[i][j] = max(f[i][k]+f[k+1][j], f[i][j]);
g[i][j] = min(g[i][k]+g[k+1][j], g[i][j]);
}
else {
f[i][j] = max(max(f[i][k]*f[k+1][j], g[i][k]*g[k+1][j]), f[i][j]);
g[i][j] = min(g[i][j], min(g[i][k]*g[k+1][j], min(g[i][k]*f[k+1][j], f[i][k]*g[k+1][j])));
}
}
}
}
LL res = -INF;
for(int i = 1; i + n - 1 < 2 * n; i++) res = max(res, f[i][i+n-1]);
printf("%lld\\n", res);
for(int i = 1; i + n - 1 < 2 * n; i++) {
if(res == f[i][i+n-1]) {
printf("%d ", i);
}
}
printf("\\n");
}
int main() {
//ios::sync_with_stdio(false);
int t = 1;
while(t--) {
solve();
}
return 0;
}
以上是关于P4342 [IOI1998]Polygon的主要内容,如果未能解决你的问题,请参考以下文章