zoukankan      html  css  js  c++  java
  • F. Clear the String(区间 DP )//每次都删除一个相同字符的子串 , 最小多少次

    https://codeforces.com/contest/1132/problem/F

    借鉴:https://www.cnblogs.com/chhokmah/p/10508762.html

    题意

    给你一个串s,每次可以花费1的代价删去一个子串,要求子串的每一位为同一个字符。
    求删去整个串的最小代价。

    分析

    这是一道非常简单的区间DP问题,我们定义dp[i][j]表示删去子串[i,j][i,j]的最小花费。
    就像合并石子一样,我们枚举中间的k,k的范围是i~j
    为了方便解决问题,将k的定义域定义成一个半闭半合区间[i,j)
    决策考虑以下:

      • 如果s[k]=s[j],那么说明当前的区间可以进行消除。
      • 反之,则不能消除。
        那么状态转移方程就是:f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+1(s[k]==s[j]))

    枚举的顺序需要注意 , 

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 502;
    char str[N];
    long long  dp[N][N];
    int main()
    {
        int n;scanf("%d%s",&n,str);
        for(int i=0 ; i<n ; i++)
        dp[i][i]=1;
    
        for(int j=1 ; j<n ; j++)
        {
            for(int i=0 ; i<j ; i++ )
            {
                dp[i][j]=0x3f3f3f3f;
    
                for(int k=i ; k<j ; k++)
                {
                    dp[i][j]=min(dp[i][j] , dp[i][k]+dp[k+1][j-1]+1-(int)(str[k]==str[j]));
                }
            }
        }
    
    //    for(int i=0 ; i<n ; i++)
    //    {
    //        for(int j=i+1 ; j<n ; j++)
    //        {
    //            dp[i][j]=0x3f3f3f3f;
    //            for(int k=i ; k<j ; k++)
    //            {
    //                dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k+1][j-1] +1 -(str[k]==str[j]));
    //            }
    //        }
    //    }
        printf("%lld
    ",dp[0][n-1]);
    }
    View Code
  • 相关阅读:
    Linux免密码登陆
    Java事务的概念
    SpringMVC访问静态资源
    堆排序
    滚动视图 UIScrollView
    HTML数据解析
    同步下载 异步下载
    项目中的小心得(以后慢慢积累起来)
    xcode 中 UIbutton图片的放置
    NSobject的基本方法使用
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/10666938.html
Copyright © 2011-2022 走看看