题目链接:http://codeforces.com/contest/814/problem/C
分析:设t[c][k]为连出长度为k的c串所需要的最小代价,暴力处理处t,然后二分找出小于等于m的最大值即可,复杂度为O(n^2+qlogn)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 const int maxn=1505,inf=2000; 7 int t[26][maxn]; 8 char s[maxn]; 9 int n,q; 10 void Calt(){ 11 vector<int>a; 12 for(int c=0;c<26;c++){ 13 a.clear(); 14 t[c][n]=inf; 15 for(int i=0;i<n;i++){ 16 t[c][i]=inf; 17 if(s[i]==c+'a') 18 a.push_back(i); 19 } 20 if(a.size()==0){ 21 for(int i=1;i<=n;i++) 22 t[c][i]=i; 23 continue; 24 } 25 t[c][1]=0; 26 for(int step=1;step<a.size();step++){ 27 for(int i=0;i<a.size()-step;i++){ 28 t[c][a[i+step]-a[i]+1]=min(a[i+step]-a[i]-step,t[c][a[i+step]-a[i]+1]); 29 } 30 } 31 for(int i=1;i<=n;i++){ 32 t[c][i]=min(t[c][i],t[c][i-1]+1); 33 } 34 } 35 } 36 int dich(char c,int m){ 37 int l=1,r=n,mid=(l+r)/2; 38 if(t[c-'a'][r]<=m)return n; 39 if(t[c-'a'][l]>=m)return 1; 40 while(l<r&&mid!=l){ 41 if(t[c-'a'][mid]>m){ 42 r=mid; 43 } 44 else{ 45 l=mid; 46 } 47 mid=(l+r)/2; 48 } 49 return mid; 50 } 51 int main(){ 52 //freopen("e:\in.txt","r",stdin); 53 cin>>n>>s>>q; 54 Calt(); 55 char c; 56 int m; 57 for(int i=0;i<q;i++){ 58 scanf("%d %c",&m,&c); 59 printf("%d ",dich(c,m)); 60 } 61 return 0; 62 }