UVA - 1625

 

白书
很明显f[i][j]表示第一个取到i第二个取到j的代价
问题在于代价的计算,并不知道每种颜色的开始和结束
 
和模拟赛那道环形DP很想,计算这次转移会给其他的元素带来的代价,也就是转移前已经出现但还没结束的元素都会代价+1
 
预处理每种颜色在两个序列中出现的位置bg[i][0/1]和ed[i][0/1],
计算f[i][j]时同时计算w[i][j]为(i,j)这个状态已经出现还没结束的个数
注意bg要先初始化为INF,计算w:
  1. if(bg[c][0]==i&&bg[c][1]>j) w[i][j]++;
  2. if(ed[c][0]==i&&ed[c][1]<=j) w[i][j]--;
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <cmath>
  6. #include <queue>
  7. using namespace std;
  8. typedef long long ll;
  9. const int N=,INF=1e9;
  10. int T,n,m;
  11. char a[N],b[N];
  12. int f[N][N],w[N][N],bg[][],ed[][];
  13. void dp(){
  14. memset(bg,,sizeof(bg));
  15. memset(ed,,sizeof(ed));
  16. for(int i=;i<;i++) bg[i][]=bg[i][]=INF;
  17. for(int i=;i<=n;i++){
  18. int c=a[i]-'A';
  19. if(bg[c][]==INF) bg[c][]=i;
  20. ed[c][]=i;
  21. }
  22. for(int i=;i<=m;i++){
  23. int c=b[i]-'A';
  24. if(bg[c][]==INF) bg[c][]=i;
  25. ed[c][]=i;
  26. }
  27. for(int i=;i<=n;i++)
  28. for(int j=;j<=m;j++){
  29. //f[i][j]=min(f[i-1][j]+cal(i-1,j),f[i][j-1]+cal(i,j-1));
  30. //f[i][j]=min(f[i-1][j],f[i][j-1])+cal(i,j);
  31. if(i==&&j==) continue;
  32. int t1=INF,t2=INF;
  33. if(i>) t1=f[i-][j]+w[i-][j];
  34. if(j>) t2=f[i][j-]+w[i][j-];
  35. f[i][j]=min(t1,t2);
  36.  
  37. if(i>){
  38. w[i][j]=w[i-][j];
  39. int c=a[i]-'A';
  40. if(bg[c][]==i&&bg[c][]>j) w[i][j]++;
  41. if(ed[c][]==i&&ed[c][]<=j) w[i][j]--;
  42. }else{
  43. w[i][j]=w[i][j-];
  44. int c=b[j]-'A';
  45. if(bg[c][]==j&&bg[c][]>i) w[i][j]++;
  46. if(ed[c][]==j&&ed[c][]<=i) w[i][j]--;
  47. //if(b[j]=='R') printf("R %d %d %d %d\n",bg[c][1],ed[c][1],i,j);
  48. }
  49. //printf("%d %d %d %d\n",i,j,f[i][j],w[i][j]);
  50. }
  51. }
  52. int main(){
  53. scanf("%d",&T);
  54. while(T--){
  55. scanf("%s%s",a+,b+);
  56. n=strlen(a+);m=strlen(b+);
  57. dp();
  58. printf("%d\n",f[n][m]);
  59. }
  60. }

白书的标程用了滚动数组,可以借鉴一下

  1. // UVa1625 Color Length
  2. // Rujia Liu
  3. #include<iostream>
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<algorithm>
  7. using namespace std;
  8.  
  9. const int maxn = + ;
  10. const int INF = ;
  11.  
  12. char p[maxn], q[maxn]; // starts from position 1
  13. int sp[], sq[], ep[], eq[]; // sp[i] start positions of character i in p
  14. int d[][maxn], c[][maxn]; // 滚动数组 c[i][j]: how many "incomplete" colors in the mixed sequence
  15.  
  16. int main()
  17. {
  18. int T;
  19. scanf("%d", &T);
  20. while(T--)
  21. {
  22. scanf("%s%s", p+, q+);
  23.  
  24. int n = strlen(p+);
  25. int m = strlen(q+);
  26. for(int i = ; i <= n; i++) p[i] -= 'A';
  27. for(int i = ; i <= m; i++) q[i] -= 'A';
  28.  
  29. // calculate s and e
  30. for(int i = ; i < ; i++)
  31. {
  32. sp[i] = sq[i] = INF;
  33. ep[i] = eq[i] = ;
  34. }
  35. for(int i = ; i <= n; i++)
  36. {
  37. sp[p[i]] = min(sp[p[i]], i);
  38. ep[p[i]] = i;
  39. }
  40. for(int i = ; i <= m; i++)
  41. {
  42. sq[q[i]] = min(sq[q[i]], i);
  43. eq[q[i]] = i;
  44. }
  45.  
  46. // dp
  47. int t = ;
  48. memset(c, , sizeof(c));
  49. memset(d, , sizeof(d));
  50. for(int i = ; i <= n; i++)
  51. {
  52. for(int j = ; j <= m; j++)
  53. {
  54. if(!i && !j) continue;
  55.  
  56. // calculate d
  57. int v1 = INF, v2 = INF;
  58. //计算d[i][j], d[i][j]由d[i-1][j]或d[i][j-1]添加一个字母得到
  59. if(i) v1 = d[t^][j] + c[t^][j]; // remove from p
  60. if(j) v2 = d[t][j - ] + c[t][j - ]; // remove from q
  61. d[t][j] = min(v1, v2);
  62.  
  63. // calculate c
  64. if(i)
  65. {
  66. c[t][j] = c[t^][j];
  67. if(sp[p[i]] == i && sq[p[i]] > j) c[t][j]++; //出现新的字母
  68. if(ep[p[i]] == i && eq[p[i]] <= j) c[t][j]--; //一个字母已经结束
  69. }
  70. else if(j)
  71. {
  72. c[t][j] = c[t][j - ];
  73. if(sq[q[j]] == j && sp[q[j]] > i) c[t][j]++;
  74. if(eq[q[j]] == j && ep[q[j]] <= i) c[t][j]--;
  75. }
  76. }
  77. t ^= ;
  78. }
  79. printf("%d\n", d[t^][m]);
  80. }
  81. return ;
  82. }

UVA - 1625 Color Length[序列DP 提前计算代价]的更多相关文章

  1. UVA - 1625 Color Length[序列DP 代价计算技巧]

    UVA - 1625 Color Length   白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束   和模拟赛那道环形DP很想,计算这 ...

  2. UVa 1625 - Color Length(线性DP + 滚动数组)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  3. UVa 1625 Color Length (DP)

    题意:给定两个序列,让你组成一个新的序列,让两个相同字符的位置最大差之和最小.组成方式只能从一个序列前部拿出一个字符放到新序列中. 析:这个题状态表示和转移很容易想到,主要是在处理上面,dp[i][j ...

  4. UVA 1625 Color Length 颜色的长度 (预处理+dp)

    dp[i][j]表示前一个序列拿了i个颜色,后一个序列拿了j个颜色的最小花费. 转移的时候显然只能向dp[i+1][j],或dp[i][j+1]转移,每增加拿走一个颜色,之前已经出现但没结束的颜色个数 ...

  5. UVA 1625 "Color Length" (基础DP)

    传送门 •参考资料 [1]:HopeForBetter •题意 •题解(by 紫书) •我的理解 用了一上午的时间,参考紫书+上述博文,终于解决了疑惑: 定义第一个颜色序列用串 s 表示,第二个用串 ...

  6. UVa 1625 Color Length

    思路还算明白,不过要落实到代码上还真敲不出来. 题意: 有两个由大写字母组成的颜色序列,将它们合并成一个序列:每次可以把其中一个序列开头的颜色放到新序列的尾部. 对于每种颜色,其跨度定义为合并后的序列 ...

  7. 洛谷P1220关路灯[区间DP 提前计算代价]

    题目描述 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少).老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯. 为了给村 ...

  8. BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]

    2726: [SDOI2012]任务安排 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 868  Solved: 236[Submit][Status ...

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

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

随机推荐

  1. java 多线程一

    java 多线程一 java 多线程二 java 多线程三 java 多线程四 java 多线程实现的几种方式: 1.extends Thread 2.implements Runnable 3.im ...

  2. js的正则表达式编程,悬赏解决下面的问题

    悬赏解决下面的问题 1.切分url 2.将时间日期 转化为 yyyy-MM-dd的模式和可逆性 3.数据的千分位和可逆性 4.用C#或者nodejs检索如下的模式 h1{ border:1px sol ...

  3. ubuntu下tensorflow 报错 libcusolver.so.8.0: cannot open shared object file: No such file or directory

    解决方法1. 在终端执行: export LD_LIBRARY_PATH=”$LD_LIBRARY_PATH:/usr/local/cuda/lib64” export CUDA_HOME=/usr/ ...

  4. Tomcat中catalina run后台运行脚本

    编写启动脚本start.sh,将其放在/srv/aubapp/bin/下 #!/bin/sh #设置web应用程序目录 export CATALINA_BASE="/srv/aubapp&q ...

  5. centos6.5/centos7安装部署企业内部知识管理社区系统wecenter

    企业内部知识系统wecenter社区系统安装及部署 centos 6.5环境安装 因为是公司内部使用在线人数不会太多,使用yum安装lamp环境即可 1.安装lamp基本环境 yum -y insta ...

  6. Ex3_15 判断图是否是一个强连通分量 判断点是否在汇点强连通分量中_十一次作业

    (a) 可以用图中的每一个顶点表示街道中的每个十字路口,由于街道都是单行的,所以图是有向图,若从一个十字路口都有一条合法的路线到另一个十字路口,则图是一个强连通图.即要验证的是图是否是一个强连通图. ...

  7. Inno Setup 系列之安装、卸载前检测进程运行情况并关闭相应进程

    需求 最近用 Inno Setup 做一个exe,可是在安装之前要停止正在运行的相应进程或者在卸载之前要停止正在运行的相应进程,可是发现它自身的方法不能满足要求,最后经过度娘的耐心帮助下终于在网上找到 ...

  8. JavaScript错误:Maximum call stack size exceeded错误

    错误的表面意思是,因为递归次数太多而内存溢出, 当然引起溢出的原因很多 找了下问题来源,发现引用了两个版本的jquery,在layout.cshtml母模块页中和视图中都引用了jq.导致循环调用,从而 ...

  9. ERP发货系统的修改(四十三)

    产品添加批号后相应修改产品库存表中对应批次产品的数量: /// <summary> /// 产品添加批号后相应修改产品库存表中对应批次产品的数量 /// </summary> ...

  10. (第2篇)一篇文章教你轻松安装hadoop

    摘要: 这篇文章将会手把手教你安装hadoop,只要你细心按照文章中的步骤操作,hadoop肯定能正确安装,绝对不会让你崩溃 博主福利 给大家赠送一套hadoop视频课程 授课老师是百度 hadoop ...