我对博客园已经非常失望了。代码也不能和文字分开了。不知道是出了什么毛病。挺讨厌乱七八糟!
这个题是典型的dp,由低往上递推。公式很简单。需要注意一个地方就是负负得正。不仅需要保存一段区间的最大值,也需要保存最小值。关于这一点我也是看了discuss后才明白的。至于为什么要这样,想想也能想明白。就不多说了。代码共参考:
#include<iostream>
#include<fstream>
#include<algorithm>
using namespace std;
const int MAX = 50 + 10;
const int INF = 3000000;
int prv[MAX], nex[MAX], d[MAX], sum[MAX][MAX], tot, minx[MAX][MAX];
char t[MAX];
void first_deal(int n)
{
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
prv[i] = n;
nex[i] = i + 1;
}else if (i == n)
{
prv[i] = n - 1;
nex[i] = 1;
}else {
prv[i] = i - 1;
nex[i] = i + 1;
}
}
}
int fun(int s, char t, int a)
{
if (t == 't')
return s + a;
else return s * a;
}
int solve(int i)
{
int x[MAX], s = i, temp;
char y[MAX];
for (int l = 1; l <= tot; l++)
{
x[l] = d[s];
y[l] = t[s];
minx[l][l] = sum[l][l] = x[l];
s = nex[s];
}
for (int p = tot - 1; p >= 1; p--)
for (int q = p + 1; q <= tot; q++)
{
int max = -INF, min = INF;
for (int l = p; l < q; l++)
{
temp = fun(sum[p][l], y[l + 1], sum[l + 1][q]);
if (max < temp)max = temp;
if (min > temp)min = temp;
temp = fun(minx[p][l], y[l + 1], minx[l + 1][q]);
if (max < temp)max = temp;
if (min > temp)min = temp;
}
sum[p][q] = max;
minx[p][q] = min;
}
return sum[1][tot];
}
int main()
{
int p[MAX], tem[MAX], k = 0, max;
cin>>tot;
first_deal(tot);
for (int i = 1; i <= tot; i++)
cin>>t[i]>>d[i];
max = -INF;
int m = 0;
for (int i = 1; i <= tot; i++)
{
int z = solve(i);
if (max < z)
{
max = z;
m = i;
}else if (max == z)
{
p[k] = max;
tem[k++] = i;
}
}
p[k] = max;
tem[k++] = m;
cout<<max<<endl;
int h = 0;
for (int i = 0; i < k; i++)
if (p[i] == max)
tem[h++] = tem[i];
sort(tem, tem + h);
for (int i = 0; i < h - 1; i++)
cout<<tem[i]<<" ";
cout<<tem[h - 1]<<endl;
return 0;
}