zoukankan      html  css  js  c++  java
  • HDU 2476 String painter

    String painter

    Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6555    Accepted Submission(s): 3168


     

    Problem Description
    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
     
     


     

    Source
     


     

    Recommend
    lcy

     

    【题意】

    给定两个相同长度的字符串A,B,每次操作可以使一个区间[l,r]变成同一个字符,问最少需要多少次操作时A变成B

     

    【分析】

    我们先考虑这样一个问题:假如A是空串,A最少需要多少次操作变成B。不难想到区间dp,设dp[i][j]为将A区间[i,j]染成B的最少操作数。

    有一个性质:如果两次染色的区间有交, 那么小的区间一定完全包含于大的区间(左右端点也不会重合), 且一定是大区间 在小区间之前染色(否则 小区间完全被覆盖 就没用了)

    所以第一次染色 一定是[i, k],   然后B[k + 1, j]可以单独考虑(因为染色不能再和[i, k]有交了)

    只要考虑B[i] = B[k]的位置, 如果不是,可以调整染色区域长度 变成右端点的颜色和 B[i]一样。

    然后有另外一个性质

    如果B[i] = B[j], dp[i][j] = dp[i + 1][j]. 只要第一次染色区域选择[i, j],  就可以和dp[i + 1][j] 对应起来。

    所以,dp[i][j]转移分为两部分:

    (1)dp[i][j]=min(dp[i][j],dp[i+1][j]+(B[i]==B[i+1]?0:1) )

    (2)dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j])  其中k满足B[i]==B[k] i<k<=j

    再考虑A串,设f[i]表示A[0]~A[i]==B[0]~B[i]的最小操作数,初始化时假设AB没有一个字符对应相同,即f[i]=dp[0][i] , f[0]特殊处理,f[0]=A[0]==B[0]?0:1; 那么f[i]考虑两部分,

    (1)  f[i]=min(f[i-1],f[i]),A[I]==B[i]  

    (2)  f[i]=min( f[i] ,f[j] +dp[j+1][i]) 其中0<=j<i ;(可将[j+1,r]视作空串)

     

    【代码】

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define debug(x) cerr<<#x<<" "<<x<<'
    ';
    using namespace std;
    const int N=110;
    int n,dp[N][N],f[N];char x[N],y[N];
    int main(){
    	while(~scanf("%s%s",x+1,y+1)){
    		n=strlen(x+1);memset(dp,0,sizeof dp);
    		for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) dp[i][j]=j-i+1;
    		for(int j=1;j<=n;j++){
    			for(int i=j-1;i>=1;i--){
    				dp[i][j]=dp[i+1][j]+!(y[i]==y[i+1]);
    				for(int k=i+1;k<=j;k++){
    					if(y[i]==y[k]){
    						dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]);
    					}
    				}
    			}
    		}
    		for(int i=1;i<=n;i++){
    			f[i]=dp[1][i];
    			if(x[i]==y[i]){
    				f[i]=f[i-1];
    			}
    			else{
    				for(int j=1;j<i;j++){
    					f[i]=min(f[i],f[j]+dp[j+1][i]);
    				}
    			}
    		}
    		printf("%d
    ",f[n]);
    	}
    	return 0;
    } 

     

     

  • 相关阅读:
    使用HTTP协下载文件
    DNS协议 实践
    操作系统学习笔记 线程
    操作系统学习笔记 进程
    操作系统学习笔记 操作系统概述
    操作系统学习笔记 栈
    操作系统学习笔记 概述
    C语言中的fread和fwrite
    【原】python-jenkins信息
    【转】通过python调用jenkins 常用api操作
  • 原文地址:https://www.cnblogs.com/shenben/p/10423228.html
Copyright © 2011-2022 走看看