zoukankan      html  css  js  c++  java
  • codeforces1196D RGB Substring (hard version) dp

    网址:http://codeforces.com/contest/1196/problem/D2

    题意:

    给出$n,k$表示字符串长度和子段长。问把原串的长度为$k$的子串变成无限长的循环字符串$“RGBRGBRGB......”$的子串的最小字符更换次数。

    题解:

    $dp[i][j]$表示主串的位置是$i$,末字母编号是$j$时,$str[1$~$i]$的代价。则转移方程是$dp[i][j]=dp[i-1][j]+(str[i]!=ch[(i+j)])$,然后$dp[i][j]-dp[i-k][j]$就是字符串在$str[i-k+1$~$i]$上的最小更换次数,取最小值即可。

    AC代码:(本代码可通过$D1$)

    #include <bits/stdc++.h>
    using namespace std;
    char ch[3]={'R','G','B'};
    int dp[200005][3];
    int main()
    {
        int T,n,m;
        cin>>T;
        string str,str2[3];
        while(T--)
        {
            cin>>n>>m;
            cin>>str;
            dp[0][0]=(str[0]!=ch[0]);
            dp[0][1]=(str[0]!=ch[1]);
            dp[0][2]=(str[0]!=ch[2]);
            for(int i=1;i<n;++i)
            {
                dp[i][0]=dp[i-1][0]+(str[i]!=ch[(i)%3]);
                dp[i][1]=dp[i-1][1]+(str[i]!=ch[(i+1)%3]);
                dp[i][2]=dp[i-1][2]+(str[i]!=ch[(i+2)%3]);
            }
            /*for(int i=0;i<3;++i)
                for(int j=0;j<n;++j)
                    cout<<dp[j][i]<<" ";
            cout<<endl;*/
            int res1=dp[m-1][0],res2=dp[m-1][1],res3=dp[m-1][2];
            for(int i=m;i<n;++i)
            {
                res1=min(res1,dp[i][0]-dp[i-m][0]);
                res2=min(res2,dp[i][1]-dp[i-m][1]);
                res3=min(res3,dp[i][2]-dp[i-m][2]);
            }
            int minn=min(res1,min(res2,res3));
            cout<<minn<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    关于asp.netCore3.0区域和路由配置
    用Autofac替换.net core 内置容器
    C#Assembly详解
    MongoDB
    Python
    Python,正则表达式
    Python
    Python
    Gevent和猴子补丁
    Django
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/11255221.html
Copyright © 2011-2022 走看看