zoukankan      html  css  js  c++  java
  • HDU2476 String painter (区间dp+简单dp)

    题目:

    There are two strings A and B with equal length. Both strings are made up of lower case letters.
    Now you have a powerful string painter. With the help of the painter, you can change a segment of
    characters of a string to any other character you want. That is, after using the painter, the segment is
    made up of only one kind of character. Now your task is to change A to B using string painter. What’s
    the minimum number of operations?
    Input
    Input contains multiple cases. Each case consists of two lines:
    • The first line contains string A.
    • The second line contains string B.
    The length of both strings will not be greater than 100.
    Output
    A single line contains one integer representing the answer.
    Sample Input
    zzzzzfzzzzz
    abcdefedcba
    abababababab
    cdcdcdcdcdcd
    Sample Output
    6
    7

    题意:

    有第一个串,变成第二个串,需要最少多少步操作,每次操作可以把一个任意区间涂成一样的颜色。

    题解:

    如果直接dp一下,那么会有在两种转移方式,当第一个串的第i个和第二个串的第i个,sum【i】=sum【i-1】.这个比较简单。

    但是如果不相等那,如果是sum【i】=sum【i-1】+1;那显然是错误的,如果,刷第i段的时候,可以和前面的某一部分一起刷,那么就会多算一次。

    那么怎么算那,可以直接暴力枚举一下,sum【i】=min(sum【i】,sum【j】+dp【j+1】【i】)j 属于(0--i)

    这样每次不相等,都从前面枚举一遍。这也是一种套路题,很多题都是这么做。但这道题的最佳dp【j+1】【i】没有给出来。也没有从前面得到。所以只能自己算一下,由空白串到第二个串的最佳刷的次数是多少,用一个区间dp求一下,每到遇到两个相同的颜色,就可以优化一下,一起刷。一直优化到最后。

    代码:

    #include<bits/stdc++.h>
    #define endl '
    '
    using namespace std;
    typedef long long ll;
    typedef double db;
    typedef pair<int,int> pii;
    typedef vector<int> vi;
    #define check system("pause")
    #define all(x) (x).begin(),(x).end()
    #define de(a) cout<<#a<<" = "<<a<<endl
    #define dd(a) cout<<#a<<" = "<<a<<" "
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define lowbit(a) ((a)&-(a))
    #define INF 0x3f3f3f3f
    const ll mod = 1e9+7;
    const int N = 101;
    #define dep(i,a,b) for(int i=(a);i>=(b);i--)
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define mes(p,b) memset(p,b,sizeof(p))
    #define sz(x) int(x.size())
    //8.43
    int dp[101][N];char a[N],b[N];
    int main()
    {
          ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        int n;
        while(cin>>a>>b){
        n=strlen(a)-1;
        int sum[N];
        mes(dp,0x3f);
        rep(i,0,n) dp[i][i]=1;
        rep(len,2,n+1)
            for(int i=0;i+len-1<=n;i++){
                int j=i+len-1;
                if(b[i]==b[j]) dp[i][j]=dp[i][j-1];
                else 
                rep(w,i,j-1){
                    dp[i][j]=min(dp[i][j],dp[i][w]+dp[w+1][j]);
                }
            }
        rep(i,0,n) sum[i]=dp[0][i];
        sum[0]=!(a[0]==b[0]);
        rep(i,1,n){
            if(b[i]==a[i]) sum[i]=sum[i-1];
            else{
                rep(j,0,i-1) sum[i]=min(sum[i],sum[j]+dp[j+1][i]);
            } 
        }
        cout<<sum[n]<<endl;
        }
          return 0;
    }
  • 相关阅读:
    第四周编程总结
    第三周编程总结
    第二周编程总结
    查找整数 编程总结
    求最大值及其下标 编程总结
    C语言I博客作业04
    C语言I博客作业03
    C语言I博客作业02
    作业01
    第八周作业
  • 原文地址:https://www.cnblogs.com/FZUlh/p/12494605.html
Copyright © 2011-2022 走看看