zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Matlab 绘制三维立体图(以地质异常体为例)
    Azure DevOps的variable group实现array和hashtable参数的传递
    Azure DevOps 利用rest api设置variable group
    Azure AADSTS7000215 其中一种问题的解决
    Power BI 实现实时更新Streaming Dataset
    AAD Service Principal获取azure user list (Microsoft Graph API)
    Matlab 沿三维任意方向切割CT图的仿真计算
    Azure Powershell script检测登陆并部署ARM Template
    Azure KeyVault设置策略和自动化添加secrets键值对
    Azure登陆的两种常见方式(user 和 service principal登陆)
  • 原文地址:https://www.cnblogs.com/alan-W/p/10800109.html
Copyright © 2011-2022 走看看