1625 - Color Length——[动态规划]
Posted kiraa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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],C[i][j]表示由A中前i个元素和B中前j个元素组成的最优新序列。下面我们考虑将颜色A[i]加入C[i-1][j]的情况。组成新序列的颜色可以分成两类:(1)已经出现还未结束的颜色 (2)已经结束的颜色 ,设第(1)类元素个数为s,那么将A[i]加入后,每个还未结束的颜色长度均要增加1,所以总长度为 d[i-1][j]+s。 这样我们就得到了状态转移方程 d[i][j]=min{d[i-1][j]+s1,d[i][j-1]+s2} ,s1为将A[i]加入C[i-1][j]的总长度增量,s2为将B[j]加入C[i][j-1]的总长度增量。
那么主要问题就转换成了如何计算C[i][j]中一景出现还未结束的颜色个数,可以对原先的两个序列预处理一遍,很容易在O(n*m)时间内计算出每个颜色开始和结束的位置。总时间复杂度为O(n*m)。
代码如下:
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 using namespace std;
5 const int maxn=100;//5000;
6
7 int d[maxn+5][maxn+5];
8 int b[2][26];
9 int e[2][26];
10 int L[26];
11 char s1[maxn+5];
12 char s2[maxn+5];
13 int n,m;
14 void init(){
15
16 memset(L, 0, sizeof L);
17 memset(b, 0, sizeof b);
18 memset(e, 0, sizeof e);
19 }
20 void pre_process(){
21 for(int i=0;i<n;i++){
22 char ch=s1[i];
23 int id=ch-‘A‘;
24 if(b[0][id]==0){
25 b[0][id]=i+1;
26 }
27 }
28 for(int i=n-1;i>=0;i--){
29 char ch=s1[i];
30 int id=ch-‘A‘;
31 if(e[0][id]==0){
32 e[0][id]=i+1;
33 }
34 }
35 for(int i=0;i<m;i++){
36 char ch=s2[i];
37 int id=ch-‘A‘;
38 if(b[1][id]==0){
39 b[1][id]=i+1;
40 }
41 }
42 for(int i=m-1;i>=0;i--){
43 char ch=s2[i];
44 int id=ch-‘A‘;
45 if(e[1][id]==0){
46 e[1][id]=i+1;
47 }
48 }
49 }
50 int sum(int i,int j,int flag){
51 int ans=0;
52 if(flag==0){
53 for(int k=0;k<26;k++) {
54 if(((b[0][k]>0&&b[0][k]<=i-1)||(b[1][k]>0&&b[1][k]<=j))&&((e[0][k]>0&&e[0][k]>i-1)||(e[1][k]>0&&e[1][k]>j)))
55 ans++;
56 }
57 }
58 else {
59 for(int k=0;k<26;k++) {
60 if(((b[0][k]>0&&b[0][k]<=i)||(b[1][k]>0&&b[1][k]<=j-1))&&((e[0][k]>0&&e[0][k]>i)||(e[1][k]>0&&e[1][k]>j-1)))
61 ans++;
62 }
63 }
64 return ans;
65 }
66
67 int main(int argc, const char * argv[]) {
68 int T;
69 scanf("%d",&T);
70 while(T--){
71 scanf("%s%s",s1,s2);
72 n=strlen(s1);
73 m=strlen(s2);
74 init();
75 pre_process();
76 d[0][0]=0;
77 for(int i=1;i<=n;i++) d[i][0]=d[i-1][0]+sum(i,0,0);
78 for(int j=1;j<=m;j++) d[0][j]=d[0][j-1]+sum(0,j,1);
79 for(int i=1;i<=n;i++){
80 for(int j=1;j<=m;j++){
81 d[i][j]=min(d[i-1][j]+sum(i,j,0),d[i][j-1]+sum(i,j,1));
82 }
83 }
84 printf("%d\n",d[n][m]);
85 }
86 return 0;
87 }
以上是关于1625 - Color Length——[动态规划]的主要内容,如果未能解决你的问题,请参考以下文章