zoukankan      html  css  js  c++  java
  • uva 1625 颜色的长度

    题目大意:

    两个字符串

    每次可以从任意一个字符串的开始选一个加入新的字符串

    定义一个字符串的价值为其各字符跨度之和,定义一个字符串内某字符跨度为该字符最后一次出现的下标与第一次出现的下标之差

    求新字符串的最小价值

    思路:

    dp

    dp数组表示第一个字符串选走了前i个,第二个选走了前j个的最小价值

    每个dp都可以从i-1,j或i,j-1转移过来

    在转移过程中,我们只需要记录一下还有多少个字符还没有结束就可以很容易的转移了

    记录这个数组还需要记录每个字符在每两个串里第一次和最后一次出现的位置

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 #include<vector>
     7 #include<queue>
     8 #include<algorithm>
     9 #define inf 2147483611
    10 #define ll long long
    11 #define MAXN 5010
    12 #define MOD 905229641
    13 using namespace std;
    14 int T,x,sa[30],ea[30],sb[30],eb[30],n,m,c[2][MAXN],dp[2][MAXN];
    15 char ca[MAXN],cb[MAXN];
    16 int main()
    17 {
    18     scanf("%d",&T);
    19     while(T--)
    20     {
    21         memset(sa,0,sizeof(sa));
    22         memset(sb,0,sizeof(sb));
    23         memset(ea,0,sizeof(ea));
    24         memset(eb,0,sizeof(eb));
    25         c[1][0]=dp[1][0]=0;
    26         scanf("%s%s",ca+1,cb+1);
    27         n=strlen(ca+1),m=strlen(cb+1);
    28         for(int i=1;i<=n;i++)
    29         {
    30             x=ca[i]-'A';
    31             if(!sa[x]) sa[x]=i;
    32             ea[x]=i;
    33         }
    34         for(int i=1;i<=m;i++)
    35         {
    36             x=cb[i]-'A';
    37             if(!sb[x]) sb[x]=i;
    38             eb[x]=i;
    39         }
    40         int p,q;
    41         bool last=1,first=0;
    42         for(int i=0;i<26;i++) {if(!sa[i]) sa[i]=inf;if(!sb[i]) sb[i]=inf;}
    43         for(int i=0;i<=n+1;i++)
    44         {
    45             for(int j=0;j<=m+1;j++)
    46             {
    47                 if(!i&&!j) continue;
    48                 p=ca[i]-'A',q=cb[j]-'A',dp[last][j]=inf;
    49                 if(i) dp[last][j]=min(dp[first][j]+c[first][j],dp[last][j]);
    50                 if(j) dp[last][j]=min(dp[last][j-1]+c[last][j-1],dp[last][j]);
    51                 if(i)
    52                 {
    53                     c[last][j]=c[first][j];
    54                     if(sa[p]==i&&sb[p]>j) c[last][j]++;
    55                     if(ea[p]==i&&eb[p]<=j) c[last][j]--;
    56                 }
    57                 if(j)
    58                 {
    59                     c[last][j]=c[last][j-1];
    60                     if(sb[q]==j&&sa[q]>i) c[last][j]++;
    61                     if(eb[q]==j&&ea[q]<=i) c[last][j]--;
    62                 }
    63             }
    64             swap(first,last);
    65         }
    66         printf("%d
    ",dp[first][m]);
    67     }
    68 }
    View Code
  • 相关阅读:
    机器学习---聚类算法
    机器学习解决问题的框架
    17个机器学习的常用算法!
    机器学习---理论篇
    golang 调用cmd执行EXE
    队列(自定义列表实现自定义队列)
    栈Stack(使用自定义链表实现自定义栈)
    链表( 自定义链表)
    队列(动态数组实现自定义队列)
    栈Stack(动态数组实现自定义栈)
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7631624.html
Copyright © 2011-2022 走看看