1. 程式人生 > >bzoj1830: [AHOI2008]Y型項鏈(LCP+貪心)

bzoj1830: [AHOI2008]Y型項鏈(LCP+貪心)

catch 不同的 lcp ont through gpo ble geo blog

1830: [AHOI2008]Y型項鏈

題目:傳送門

簡要題意:

   給出三個字符串,可以對任意字符串進行操作,每次操作都可以再其中一個字符串的末尾刪除或添加一個字符,求最小操作數使得所有的字符串相同

題解:

   一開始沒有看到只有三個串

   仔細想想發現會是一道水ti:

   因為只有三個串嘛,而且n才50,那就對任意兩個串都跑一下LCP,找出匹配率最高的兩個串,然後就可以開始真正的操作了:

   首先:對於匹配率最高的兩個串,對串進行刪除使它變短或者進行添加使它變長所需要的操作數是一樣的(比如CATB和CATCHA)

   但是當對第三個串操作的時候影響是不同的:對於第三個串,要麽什麽都不用做,要麽刪了再加,要麽直接加

   對於後面兩種情況,肯定都只用在乎加了多少(那肯定越少越好),那麽在前面對匹配率高的兩個串進行操作時,肯定讓它變短啦!

   nice雙倍經驗(沒有搞懂AHOI的操作)

代碼:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int len,len1,len2,len3,maxx,k;
 8 char
s1[110],s2[110],s3[110]; 9 void get_LCP() 10 { 11 int i=1;maxx=0;k=0; 12 while(s1[i]==s2[i] && i<=len1 && i<=len2)i++; 13 if(maxx<i)maxx=i-1,k=3; 14 i=1; 15 while(s1[i]==s3[i] && i<=len1 && i<=len3)i++; 16 if(maxx<i)maxx=i-1
,k=4; 17 i=1; 18 while(s2[i]==s3[i] && i<=len2 && i<=len3)i++; 19 if(maxx<i)maxx=i-1,k=5; 20 } 21 int main() 22 { 23 scanf("%d",&len1);scanf("%s",s1+1); 24 scanf("%d",&len2);scanf("%s",s2+1); 25 scanf("%d",&len3);scanf("%s",s3+1); 26 get_LCP(); 27 if(k==3) 28 { 29 int ans=0; 30 ans+=abs(len1-maxx)+abs(len2-maxx);int i=1; 31 while(i<=maxx && s1[i]==s3[i])i++; 32 i--; 33 ans+=(len3-i+maxx-i); 34 printf("%d\n",ans); 35 } 36 if(k==4) 37 { 38 int ans=0; 39 ans+=abs(len1-maxx)+abs(len3-maxx);int i=1; 40 while(i<=maxx && s1[i]==s2[i])i++; 41 i--; 42 ans+=(len2-i+maxx-i); 43 printf("%d\n",ans); 44 } 45 if(k==5) 46 { 47 int ans=0; 48 ans+=abs(len2-maxx)+abs(len3-maxx);int i=1; 49 while(i<=maxx && s1[i]==s2[i])i++; 50 i--; 51 ans+=(len1-i+maxx-i); 52 printf("%d\n",ans); 53 } 54 return 0; 55 }

bzoj1830: [AHOI2008]Y型項鏈(LCP+貪心)