1. 程式人生 > >Codeforces Round #418 (Div. 2) C. An impassioned circulation of affection

Codeforces Round #418 (Div. 2) C. An impassioned circulation of affection

這題題目有點歧義garland 意思是花圈,於是,把題意理解成了在環上找最長同一字母序列。而實際上,題目意思,仍是一個串。

這題顯然可以預處理答案,實際上,對於每種詢問(m,c),可以簡單貪心一下,最佳策略肯定是去連線某些不連續的段(只包含字元c),而連線的最低要求是起始和結尾都是一個c字元。於是我們可以假設,最佳答案都是以一個字元c開頭(這裡說法並不對,可以以非c字元開始,將其染成c字元,但為了表述方便,先這樣描述),那麼對於以某個字元開頭,經過最多m次染色可以得到的最長c字元序列可以求出。向右貪心,儘可能延伸c字串的長度。求出這個結果並不是答案,因為實際上,字串還可以向左擴充套件,但是我們只關心最長長度,所以只有當右邊全部變成c字元後,我們可以用多餘的染色機會去染左邊的位置。對答案來說,直接加上剩餘的染色次數,與n取小即可。

上述操作,兩個迴圈就可以完成,因此複雜度位O(N^2)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<list>
#include<bitset>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
int n,m;
char str[1502];
int dp[50][1505];
int main()
{
    while(~scanf("%d",&n))
    {
        getchar();
        memset(dp,0,sizeof dp);
        gets(str);
        for(int i=0;i<26;i++)
            for(int j=0;j<=n;j++)
            dp[i][j]=j;
        for(int i=0;i<n;i++)
        {
            int p=str[i]-'a';
            dp[p][0]=1;
            int tmp=1,pp=i+1;
            for(int j=0;j<=n;)
            {
                if(pp>=n||str[i]!=str[pp]) j++;
                tmp++;
                tmp=min(tmp,n);
                dp[p][j]=max(dp[p][j],tmp);
                pp++;
            }
        }
        scanf("%d",&m);
        int cnt;
        char arg[5];
        for(int i=1;i<=m;i++)
        {
            scanf("%d %s",&cnt,arg);
            char ch=arg[0];
            printf("%d\n",dp[ch-'a'][cnt]);
        }
    }
   return 0;
}