String Master 【贪心】
本人水平有限,题解不到为处,请多多谅解
本蒟蒻谢谢大家观看
题目:
String Master(master.c/cpp/pas)
Input fifile: master.in
Output fifile: master.out
Time limit: 1 seconds
Memory limit: 128 megabytes
所谓最长公共子串,比如串 A:“abcde”,串 B:“jcdkl”,则它们的最长公共子串为串 “cd”,即长
度最长的字符串,且在两个串中都作为连续子串出现过。
给定两个长度都为 n 的字符串,对于字符串大师的你来说,求它们的最长公共子串再简单不过了。
所以现在你有 k 次修改机会,每次你可以选择其中某个串的某个位置,将其修改成任意字符。
你需要合理使用这 k 次修改机会,使得修改之后两个串的最长公共子串最长。相信对于字符串大师
的你来说,这个问题也难不倒你。
Input
第一行包含两个整数 n, k,分别表示字符串的长度和修改次数。
第二行包含一个长度为 n 的仅由小写字符构成的字符串 S。
第三行包含一个长度为 n 的仅由小写字符构成的字符串 T。
Output
输出一行一个整数,即修改完毕之后两个串的最长公共子串的长度。
Sample Input1
5 0
abcde
jcdkl
abcde
jcdkl
Sample Output1
Sample Input2
5 2
Sample Output2
aaaaaababa
本题拥有贪心思想。
贪心策略如下:
我们用一个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 */