UVA 1625 Color Length 颜色的长度

dp[i][j]表示前一个序列拿了i个颜色,后一个序列拿了j个颜色的最小花费。

转移的时候显然只能向dp[i+1][j],或dp[i][j+1]转移,每增加拿走一个颜色,之前已经出现但没结束的颜色个数的跨度都增加1,为了在转移的时候快速算出这个值,先预处理出每个颜色在各个序列中的起始和终止位置。

memset (dp),然后就GG了

#include<bits/stdc++.h>
using namespace std;

#define FOR(i,s,e) for(int i = s; i < e; i++)
#define RFOR(i,e,s) for(int i = e-1; i >= s; i--)
#define bug(x) cout<<#x<<‘=‘<<endl

#define MP make_pair
#define PB push_back
#define fi first
#define se second

#define CLR(x) memset(x,0,sizeof(x));
#define CLRTo(x,v) memset(x,v,sizeof(x));

const int maxn = 5001;

int dp[maxn][maxn];

const int N = 26;
char s1[maxn];
char s2[maxn];
bool vis[N];
int ed2[N],ed1[N];
int st1[N],st2[N];

#define GetEd(x)\
CLR(vis);for(i = n##x-1; i >= 0; i--){    int id = s##x[i] - ‘A‘;    if(!vis[id]){        vis[id] = true;        ed##x[id] = i;    }}

#define GetSt(x)\
CLR(vis);for(i = 0; s##x[i]; i++){    int id = s##x[i] - ‘A‘;    if(!vis[id]){        vis[id] = true;        st##x[id] = i;    }}n##x = i;

int cal(int i,int j)
{
    int ret = 0;
    for(int k = 0; k < N; k++){
        bool f1 = j>=st2[k] || i>=st1[k];
        bool f2 = j<ed2[k] || i < ed1[k];
        ret += f1&&f2;
    }
    return ret;
}

const int INF = 0x3fffffff;

int main()
{
    //freopen("in.txt","r",stdin);
    int T; scanf("%d",&T);
    while(T--){
        scanf("%s%s",s1,s2);
        int i;
        int n1 ,n2 ;
        fill(st1,st1+N,INF);
        fill(st2,st2+N,INF);
        fill(ed1,ed1+N,-INF);
        fill(ed2,ed2+N,-INF);
        GetSt(1) GetSt(2)
        GetEd(1) GetEd(2)
        for(i = 0; i <= n1; i++){
            for(int j = 0; j <= n2; j++){
                if(i&&j){
                    dp[i][j] = min(dp[i-1][j],dp[i][j-1])+cal(i-1,j-1);
                }else {
                    if(i){
                        dp[i][j] = dp[i-1][j]+cal(i-1,j-1);
                    }else if(j){
                        dp[i][j] = dp[i][j-1]+cal(i-1,j-1);
                    }else {
                        dp[i][j] = 0;
                    }
                }
            }
        }
        printf("%d\n",dp[n1][n2]);
    }
    return 0;
}
时间: 2024-08-07 14:32:49

UVA 1625 Color Length 颜色的长度的相关文章

uva 1625 - Color Length(dp 里面 L C S 问题解决方式变形)

LCS属线性结构上的动态规划,应该是动规里面很简单的一种类型. 最长公共子序列问题,一旦明确了状态,找到状态转移方程还是很简单的.但是对于本题来说,难点之一就是会很难想到该如何定义状态. 作为一只菜鸟,兹认为此题很复杂. 首先我是想不到每一步都把没到终点的字母全加上1,以及这种效果与你去找开始和结束的效果是一样的. 甚至,若不是在做动规的专题,我根本想不到这样的题目,会用动规来解决. 再一个,我想不到状态可以这么来定义"设d[ i ][ j ]表示两个序列分别已经拿出去了 i 个和 j 个元素

UVa 1625 Color Length

思路还算明白,不过要落实到代码上还真敲不出来. 题意: 有两个由大写字母组成的颜色序列,将它们合并成一个序列:每次可以把其中一个序列开头的颜色放到新序列的尾部. 对于每种颜色,其跨度定义为合并后的序列中最后一次和第一次出现的位置之差,求所有合并方案中所有颜色跨度之和的最小值. 分析: d(i, j)表示两个串分别已经移走了i个和j个字符.那么无论新串的顺序是什么,有多少种颜色已经开始但尚未结束是确定的,记为c(i, j).再继续移走一个字符,所有颜色跨度之和就增加c(i, j).c的计算是通过记

UVA 1625 Color Length DP

题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4500 题目描述: 两个字符串 ,组成一个新的字符串, 每次只能从其中一个的开头选一个加到新的尾, 问l(i)的最小值 解题思路: dp(i, j)  表示从第一个字符串中取i 个, 第二个字符串中取j个时的最优方案, 我们创建数组c 表示从第一个字符串中取i 个, 第二个字符串

UVA 1625 Color Length (DP)

题意:见紫书P276 思路:(设一个颜色序列为s1,另一个为s2)要把最优子结构找到是关键,状态就是天然的执行步骤,d(i,j)表示s1移走了i个元素 s2移走了j个元素的状态.下一步只有两个决策,决策后的剩余的问题和原问题一样,这就是最优子结构.所以每次决策时要保证决策的产生的花费+子问题的解达到最优 所以状态方程显然:dp[i][j]=min(dp[i+1][j],dp[i][j+1])+res[i][j] 本题的难点在于求res[i][j],所以要在之前对字符串做预处理 代码: //0 K

1625 - Color Length——[动态规划]

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4500 题目分析: 本题要将两条路上的车辆混合成一路,混合方法可以是:每次将一个颜色序列中的开头颜色放入新序列的尾部.可以定义状态d[i][j]为第一个序列移走了i辆车,第2个序列移走了j辆车时,新序列的颜色长度.如何进行状态转移呢? 假设第一个序列为A[n],第二个序列为B[m]

动态规划(模型转换):uvaoj 1625 Color Length

[PDF Link]题目点这里 这道题一眼就是动态规划,然而貌似并不好做. 如果不转换模型,状态是难以处理的. 巧妙地转化:不直接求一种字母头尾距离,而是拆开放到状态中. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int maxn=5010; 6 char s1[maxn],s2[maxn]; 7 int B1[26],E1[

UVA1625 / UVALive 5841 Color Length DP

简单DP,dp[i][j]表示从第一个序列里取出i个和从第j个序列里取出j个的组合的最小值,可以从两个方向转移过来,每次转移加上已经出现过的且还没有出现完的字母的个数. O(n?m)的复杂度. 1625 Color Length Cars painted in different colors are moving in a row on the road as shown in Figure 1. The color of each car is represented by a single

uva1625 Color Length 线性动态规划

// uva1625 Color Length // 这是好久之前在紫书(page 276)上看到的题目了 // 题目的意思是,给你两个长度分别为n和m的颜色序列(n,m<=5000) // 都是由大写字母组成,要求按照顺序合并成同一个序列,即每次 // 可以把一个序列开头的颜色放在新序列的尾部 // 比如两个序列:GGBY 和 YRRGB至少有两种合并结果: // GBYBRYRGB 和 YRRGGBBYB 对于每一种颜色c,跨度L(c)是最大位置和 // 最小位置之差, // 问题是: 找一

UVa1625 Color Length

/*----UVa1625 Color Length --用dp[i][j]表示当前两个串分别移走到第i和第个元素j时所获得的目标函数最优值,首先计算出两个序列中的每个元素开始和 结束的位置,在计算dp[i][j]的同时,还需要记住当前有多少颜色已经开始但是没有结束,这样不必关心每一个元素的L(c), 在程序递进计算的同时,只需要每次累加已经开始还没结束的元素个数即可. */ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #includ