• Color Length UVA


    题目大意:

    给你两个字符串p,q,字符串中每个字符代表一个颜色,现在按顺序合并两个字符串,得到一个新字符串。新字符串的价值为,每个颜色价值的和,单个颜色价值的和等于该颜色在新字符中最后一次出现的位置减去第一次出现的位置。求最小价值

    题目思路:

    dp[i][j]代表使用p的前i个字符,q的前j个字符合并产生的价值。对于dp[i][j],可由dp[i-1][j],dp[i][j-1]转移得到,每次转移增加的价值为【已被填入,但尚未填完的颜色的个数】。

    用c[][]维护当前已被填入但尚未被填完的颜色的数目,若一个颜色新加入就加一,若一个颜色被填完就减一。

    由于dp[5000][5000]太大了,且每次转移仅与dp[i-1][j],dp[i][j-1]有关,我们可以采用滚动数组优化

    #pragma GCC optimize(2)
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<stdlib.h>
    #include<iostream>
    #include<stack>
    #include<vector>
    #include<math.h>
    using namespace std;
    #define LL long long
    #define INF 0x3f3f3f3f
    
    int dp[2][5001];
    int c[2][5001];
    char s1[5005],s2[5005];
    struct node
    {
        int s,e;
    } p1[30],p2[30];
    
    int main()
    {
        int n;
        scanf("%d",&n);
        //cout << (int) 'Y'-'A' << endl;
        while(n--)
        {
            for(int i=0; i<26; i++)
            {
                p1[i].s = p2[i].s = INF;
                p1[i].e = p2[i].e = -1;
            }
            scanf("%s",s1+1);
            scanf("%s",s2+1);
            int l1 = strlen(s1+1);
            int l2 = strlen(s2+1);
            for(int i=1; i<=l1; i++)
            {
                int id = s1[i] - 'A';
                if(p1[id].s == INF)
                    p1[id].s = i;
                p1[id].e = i;
            }
            for(int i=1; i<=l2; i++)
            {
                int id = s2[i] - 'A';
                if(p2[id].s == INF)
                    p2[id].s = i;
                p2[id].e = i;
            }
            int t = 0;
            memset(c,0,sizeof(c));
            memset(dp,0,sizeof(dp));
            for(int i=0; i<=l1; i++)
            {
                for(int j=0; j<=l2; j++)
                {
                    if(!i && !j)
                        continue;
                    int v1=INF,v2=INF;
                    if(i)
                        v1 = dp[t^1][j] + c[t^1][j];
                    if(j)
                        v2 = dp[t][j-1] + c[t][j-1];
                    dp[t][j] = min(v1,v2);
    
                    if(i)
                    {
                        c[t][j] = c[t^1][j];
                        if(p1[s1[i]-'A'].s == i && p2[s1[i]-'A'].s>j)
                            c[t][j]++;
                        if(p1[s1[i]-'A'].e == i && p2[s1[i]-'A'].e <= j)
                            c[t][j]--;
                    }
                    if(j)
                    {
                        c[t][j] = c[t][j-1];
                        if(p2[s2[j]-'A'].s == j && p1[s2[j]-'A'].s>i)
                            c[t][j]++;
                        if(p2[s2[j]-'A'].e == j && p1[s2[j]-'A'].e <= i)
                            c[t][j]--;
                    }
                }
                t ^= 1;
            }
            printf("%d
    ",dp[t^1][l2]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    del
    sublime右键菜单,anaconda设置
    全概率公式、贝叶斯公式推导过程
    python数据结构之链表(一)
    关于panda中dataframe的与&运算*(stackoverflow高票答案)
    转载:python 日期,季度,年份
    商业模式画布
    互联网思维
    互联网思维
    战略品牌管理_1
  • 原文地址:https://www.cnblogs.com/alan-W/p/10800109.html
Copyright © 2020-2023  润新知