这道题是典型的区间DP,老师给我们小学期的DP就这么难。。。。。现在才能刷完。
这道题其实可以跟石子合并问题归为一类。(三种.....)
不过这里要注意一点就是有乘法运算,乘法可能将两个最小的数字变为最大的,所以在dp过程中要记录最大最小值。自认为代码还比较能看。
这里还要输出起初去掉的边,DP完后直接扫一遍。(环形特征,注意取模)
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#define inf (1<<30)
using namespace std;
typedef long long ll;
const int maxn=10+100;
int dp[maxn][maxn][2];
char edge[maxn];
int number[maxn];
int N,M;
int main()
{
while(~scanf("%d",&N))
{
for(int i=0;i<N;i++)
cin>>edge[i]>>number[i];
edge[N]=edge[0];
memset(dp,0,sizeof(dp));
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
if(i==j)
dp[i][j][0]=dp[i][j][1]=number[i];
else dp[i][j][0]=-inf,dp[i][j][1]=inf;
int ans=-inf;
for(int len=1;len<N;len++)
for(int i=0,j=i+len;i<N;i++,j++)
{
for(int k=i;k<j;k++)
{
if(edge[(k+1)%N]=='t')
dp[i%N][j%N][0]=max(dp[i%N][j%N][0],dp[i%N][k%N][0]+dp[(k+1)%N][j%N][0]),
dp[i%N][j%N][1]=min(dp[i%N][j%N][1],dp[i%N][k%N][1]+dp[(k+1)%N][j%N][1]);
else
dp[i%N][j%N][0]=max(dp[i%N][j%N][0],dp[i%N][k%N][0]*dp[(k+1)%N][j%N][0]),
dp[i%N][j%N][0]=max(dp[i%N][j%N][0],dp[i%N][k%N][1]*dp[(k+1)%N][j%N][1]),
dp[i%N][j%N][1]=min(dp[i%N][j%N][1],dp[i%N][k%N][1]*dp[(k+1)%N][j%N][1]),
dp[i%N][j%N][1]=min(dp[i%N][j%N][1],dp[i%N][k%N][0]*dp[(k+1)%N][j%N][1]),
dp[i%N][j%N][1]=min(dp[i%N][j%N][1],dp[i%N][k%N][1]*dp[(k+1)%N][j%N][0]);
if(len==N-1)
ans=max(dp[i][j%N][0],ans);
}
}
printf("%d\n",ans);
int aa[100];int k=0;
for(int i=0;i<N;i++)
if(dp[i][(i-1+N)%N][0]==ans)
aa[k++]=i+1;
for(int i=0;i<k;i++)
if(i==k-1) printf("%d\n",aa[i]);
else printf("%d ",aa[i]);
}
return 0;
}
更新:
这道题做了以后发现石子合并问题的三种中第三种跟这个很像,于是学习一下。
问题:一堆石子,每个石子都有其价值要求两两合并,使得价值最大/最小。
1.每次的石子都任意选取。 跟哈夫曼一样。
2.排成一条线,每次只能选取相邻的。子集覆盖括号匹配问题,使用矩阵链乘的DP方案。
3.直线变为环。这个是关键点。也于本题相似。其思路是换了一种dp[i][j]的表示意思,即从i开始合并j个的最小价值。
其本质并未变,与原先意思也差不多。代码则是j在外层表示长度,i表示起始位置。(用之前的表示也没什么不妥的,就是改变一个内循环的次数到n即可)
动态规划四边形优化:
1.满足四边形不等式
w[i,j] + w[i‘,j’] <= w[i‘,j] + w[i,j’] (i<=i‘<j<=j’)
2.满足区间包含单调性
w[i’,j] <= w[i,j’] (i<=i‘<j<=j’)那么对于
m[i,j]=min{m[i,k-1]+m[k,j]+w[i,j]} (i<k<=j)
如果w[i,j]满足四边形不等式和区间包含单调性,那么m[i,j]也满足四边形不等式。 用s[i,j]表示m[i,j]的决策,如果函数m[i,j]满足四边形不等式,则函数s[i,j]满足单调性,即决策单调性: s[i,j]<=s[i,j+]<=s[i+1,j+1]。
其证明我是没看懂。掌握:当m[i,j]=min{m[i,k-1]+m[k,j]+w[i,j]} (i<k<=j) 中w[i,j]满足两个性质的时候,k的取值不用全部枚举。只需从s[i][j-1]~s[i+1][j]枚举即可