以下是出错代码
如果把记忆化的部分删去,即可AC前三点(后两个TLE,意思就是答案算的是对的)
但是加了记忆化就出错,想不明白。。
#include<iostream>
#define int long long
using namespace std;
const int N=50;
int n,a[N],dp[N][N],mx,rt[N][N],f[N][N];
int ans;
int dfs(int l,int m,int r)//在l到r区间中,以m为根的最优解
{
if(l==r)
{
dp[l][r]=a[l];rt[l][r]=l;
return m;
}
int r1=0,r2=0;
int mx1=1,mx2=1;
if(f[l][m-1])r1=rt[l][m-1],mx1=dp[l][m-1];//发现该区间被查找过,直接存下答案
else for(int i=l;i<m;++i)
{
int s=dfs(l,i,m-1);
if(dp[l][m-1]>=mx1)mx1=dp[l][m-1],rt[l][m-1]=s;
if(i==m-1)f[l][m-1]=1;//l到m-1区间完成查找,标记一下
}
if(f[m+1][r])r2=rt[m+1][r],mx2=dp[m+1][r];//发现该区间被查找过,直接存下答案
else for(int i=m+1;i<=r;++i)
{
int s=dfs(m+1,i,r);
if(dp[m+1][r]>=mx2)mx2=dp[m+1][r],rt[m+1][r]=s;
if(i==r)f[m+1][r]=1;//m+1到r区间完成查找,标记一下
}
dp[l][r]=mx1*mx2+a[m];
return m;
}
void prt(int l,int r)
{
cout<<rt[l][r]<<" ";
if(rt[l][r]>l)prt(l,rt[l][r]-1);
if(rt[l][r]<r)prt(rt[l][r]+1,r);
}
signed main()
{
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;++i)
cin>>a[i];
for(int i=1;i<=n;++i)
{
int as=dfs(1,i,n);
if(dp[1][n]>mx)mx=dp[1][n],rt[1][n]=as;
}
cout<<mx<<endl;
prt(1,n);
return 0;
}