题目描述
blablabla
样例
blablabla
和石子合并类似的区间dp一般都是这样转移的
算法
(区间dp) $O(n^3)$
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N=205;
const int inf=32768;
char c[N];
int w[N],f[N][N],g[N][N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>c[i]>>w[i];
c[i+n]=c[i];
w[i+n]=w[i];
}
//进行dp
memset(g,0x3f,sizeof g);
memset(f,-0x3f,sizeof f);
for(int len=1;len<=n;len++)
{
for(int l=1;l<=2*n;l++)
{
int r=l+len-1;
if(l==r) f[l][r]=g[l][r]=w[l];
for(int k=l;k<r;k++)
{
if(c[k+1]=='t')
{
f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]);
g[l][r]=min(g[l][r],g[l][k]+g[k+1][r]);
}
else
{
f[l][r]=max(f[l][r],f[l][k]*f[k+1][r]);
f[l][r]=max(f[l][r],f[l][k]*g[k+1][r]);
f[l][r]=max(f[l][r],g[l][k]*f[k+1][r]);
f[l][r]=max(f[l][r],g[l][k]*g[k+1][r]);
g[l][r]=min(g[l][r],f[l][k]*f[k+1][r]);
g[l][r]=min(g[l][r],f[l][k]*g[k+1][r]);
g[l][r]=min(g[l][r],g[l][k]*f[k+1][r]);
g[l][r]=min(g[l][r],g[l][k]*g[k+1][r]);
}
}
}
}
//输出答案.
int ans=-inf;
for(int i=1;i<=n;i++) ans=max(ans,f[i][i+n-1]);
cout<<ans<<endl;
for(int i=1;i<=n;i++)
{
if(ans==f[i][i+n-1])
{
cout<<i<<' ';
}
}cout<<endl;
return 0;
}