1 条题解

  • 3
    @ 2023-7-5 1:12:53

    解题步骤:

    step 1: 设立状态。按照惯例,设f[i][j]表示从i到j的区间修改为目标状态的所需步数

    step 2: 初始化。长度为1的区间可以直接算出,从没有涂色到给定的颜色需要涂一次色。

    step 3: 枚举起点、终点,推出答案。 当第i个字符与第j个字符相同时,只需在第一次涂色时多涂一个即可。所以f[i][j]=min(f[i+1][j],f[i][j-1]) (缩小区间) 不同时,枚举断点k(i<=k<j),则f[i][j]=断点左边修改次数+断点右边修改次数,即f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);

    step 4: 输出。结果=f[1][n];

    附上dp代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    const int N=55;
    int f[N][N];
    char a[N];
    // 区间DP:f[i][j]表示把从i到j的字符串修改为目标状态需要多少次
    int main(){
        scanf("%s",a+1);
        int n=strlen(a+1);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i==j)
                    f[i][j]=1;
                else
                    f[i][j]=1<<30; //因为答案要求最小,所以初始化要大
            }
        }
        for(int l=2;l<=n;l++){//模板
            for(int i=1;i<=n;i++){
                int j=i+l-1;
                if(j>n)
                    break;
                if(a[i]==a[j])//相同时
                    f[i][j]=min(f[i+1][j],f[i][j-1]);
                for(int k=i;k<j;k++)//不同时
                    f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
            }
        }
        printf("%d\n",f[1][n]);
        //system("pause");
        return 0;
    }
    

    还有记忆化搜索代码: (事实说明dfs更好点:dp-47ms/1800多kb, dfs-28ms/820kb)

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    const int N=55;
    int f[N][N],n;
    char a[N];
    int dfs(int l,int r){ //模板
        if(l==r)
            return f[l][r]=1;//递归到底层,相当于dp中的初始化条件
        if(f[l][r]!=-1)
            return f[l][r];//已经计算过了,调用
        int tmp=1<<30;
        if(a[l]==a[r])
            tmp=min(dfs(l+1,r),dfs(l,r-1));//解释同dp代码
        for(int k=l;k<r;k++)
            tmp=min(tmp,dfs(l,k)+dfs(k+1,r));
        return f[l][r]=tmp;
    }
    int main(){
        scanf("%s",a+1);
        n=strlen(a+1);
        memset(f,-1,sizeof(f));//标记为没有计算过
        printf("%d\n",dfs(1,n));
        return 0;
    }
    
    • 1

    信息

    ID
    244
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    144
    已通过
    78
    上传者