zoukankan      html  css  js  c++  java
  • bzoj 1260 (区间dp)

    传送门

    题意:

    给你一串由大写字符组成的长度为(n)字符串,现在你每次可以让区间([l,r])的所有字符变成任意一种字符。现在问你把一个长度为(n)的空串变为指定的字符串需要多少多少次操作。

    分析:

    这个问题在基础区间dp中夹杂了贪心的思想。

    我们考虑(dp[l][r])为区间([l,r])进行染色取得了对应的值的最小的操作数。在此基础上,我们贪心的考虑,对于一个大的区间([l,r]),倘若区间两端的字符是相同的,即(str[l]==str[r]),要使得答案更优,则这个大的区间只需要通过子区间([l+1,r])或者子区间([l,r-1]),通过染成同一种颜色,花费(1)点代价转移而来。而倘若区间两端的字符不相同,则这段区间是由这段区间的两个子区间转移而来的,此时我们只需要用最基本的区间dp的讨论,通过枚举断点(k)进行状态转移。

    代码:

    #include <bits/stdc++.h>
    #define maxn 105
    using namespace std;
    int dp[maxn][maxn],a[maxn];
    char str[maxn];
    const int inf=0x3f3f3f3f;
    int main()
    {
        scanf("%s",str+1);
        int n=strlen(str+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dp[i][j]=inf;
        for(int i=1;i<=n;i++){
            dp[i][i]=1;
        }
        for(int p=1;p<=n;p++){
            for(int i=1,j=i+p;j<=n&&i<=n;i++,j=i+p){
                if(str[i]==str[j]) dp[i][j]=min(dp[i+1][j],dp[i][j-1]);
                else
                    for(int k=i;k<j;k++){
                        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
                    }
            }
        }
        printf("%d
    ",dp[1][n]);
        return 0;
    }
    
    
  • 相关阅读:
    【第三章】DI的配置使用(一)
    【第二章】IoC的配置使用(一)
    【第二章】IoC的基础与详解(一)
    【第一章】 Spring概述(二)
    【第一章】 Spring概述(一)
    数据库分库分表思路
    Java的内存模型JVM
    Servlet 单例多线程详细解释
    三极管
    续流二极管
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11216286.html
Copyright © 2011-2022 走看看