私は、理解の多くは、問題の解決策ではない、制限されています
このこんにゃくを見ていただきありがとうございます
トピック:
文字列マスター(master.c / CPP / PAS)
入力fifile:master.in
master.out:fifile投稿
制限時間:1秒
メモリ制限:128メガバイト
そのような文字列Aとして、いわゆる最長共通文字列、「ABCDE」の文字列B:「jcdkl」、次いでその最長共通文字列が文字列「CD」である、すなわち、ロング
最長の文字列の、そして二つのサブ文字列での連続文字列として登場しています。
あなたは、長さの2つの文字列を考えるとnは、マスターのための文字列が、彼らは最長共通部分が容易になる見つけます。
だから今、あなたは、あなたが任意の文字に編集して、文字列の場所を選択することができますたびに、k回を修正する機会を持っています。
あなたは最長の最長共通部分文字列を変更するために2つの文字列を作った後、この機会k回の使用の合理化を変更する必要があります。私は、マスター列と信じています
あなたのために、この問題はあなたを破っていません。
入力
最初の行は、修正文字列の長さと数を表す2つの整数N、Kを含んでいます。
2行目は、小文字のみからなる文字列を含むN S.
三行目は小文字N T.のみからなる文字列を含みます
出力
出力線整数、すなわち変形後の二つの文字列は、最長共通部分の長さを完成します。
サンプル入力1
5 0
ABCDE
jcdkl
ABCDE
jcdkl
サンプル出力1
サンプル入力2
5 2
サンプル出力2
AAAAAアベバ
この質問は貪欲な考えを持っています。
次のように貪欲な戦略は次のとおりです。
我们用一个limit表示当上下两个字符串不相等时能加到的最大上限值,当limit大于k时,我们就回溯break,我们能保
证为最优的。开三个for循环,分别枚举字符串a,字符串b,以及当前能到达的最大个数。
这时我们要不断的sum++。因为有k后悔的存在,保证我们求出相等段数的最大值。最后在用ans来存最大值即可。
code:
1 #include<bits/stdc++.h> 2 #pragma GCC optimize(3) 3 using namespace std; 4 int n,k,ans; 5 char s[1001]; 6 char ch[1001]; 7 void inint(){ 8 freopen("master.in","r",stdin); 9 freopen("master.out","w",stdout); 10 } 11 inline int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 15 return x*f; 16 } 17 inline void write(int x) 18 { 19 if(x<0)x=-x,putchar('-'); 20 if(x>9)write(x/10); 21 putchar(x%10+'0'); 22 } 23 int main() 24 { 25 //inint(); 26 n=read(),k=read(); 27 scanf("%s",s+1); 28 scanf("%s",ch+1); 29 for(int i=1;i<=n;i++){ 30 for(int j=1;j<=n;j++){ 31 int limit=0,sum=0; 32 for(int kk=0;i+kk<=n&&j+kk<=n;kk++){//不能超过上限的n 33 if(s[i+kk]!=ch[j+kk]){ 34 limit++;//使用k 35 } 36 if(limit>k){//使用次数超过k时,回溯 37 break; 38 } 39 //cout<<"k= "<<k<<" i= "<<i<<" j= "<<j<<" limit= "<<limit<<endl; 40 41 sum++;//累加相同的,如果k=0的话,如果不相等时,会不断回溯。 42 } 43 ans=max(ans,sum);//存最大值 44 } 45 } 46 printf("%d\n",ans); 47 return 0; 48 } 49 /* 50 51 5 0 52 abcde 53 jcdkl 54 2 55 5 2 56 aaaaa 57 ababa 58 5 59 10 3 60 abcdefghij 61 kkkyzlabcd 62 63 */