求助,不知道这样记忆化为什么会出错(有注释)
查看原帖
求助,不知道这样记忆化为什么会出错(有注释)
213535
Bluebird_楼主2023/8/8 16:11

以下是出错代码

如果把记忆化的部分删去,即可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;
}
2023/8/8 16:11
加载中...