題解西電OJ (Problem 1005 -跳舞毯)--動態規劃

 

Description

  zyf不當心得了一種怪病,爲了維持一天的精力他必須不停跳動。因而他買了一條跳舞毯,天天跳上幾小時。衆所周知,跳舞毯是給定一個序列,讓你在指定時間踏指定的按鈕,但zyf彷佛不怎麼擅長,爲此他寫了個外掛,以修改它的輸入序列,獲得滿分!
  這個外掛的厲害之處在於它能等到zyf跳完、輸入序列後再進行修改,修改的方式有三種,在任意位置插入、刪除或替換一個指令,每次插入須要a時間,刪除須要b時間,替換須要c時間,如今zyf想用最短期去修改他輸入的序列獲得滿分(即與給定序列同樣),但這顯然已經超過了當前外掛的能力範圍,因而只好求助於你,給這外掛寫個補丁。
ios

Input
  輸入包含多組數據,EOF結束。
  每組數據包括三行,第一行包含三個整數a,b,c(0<a,b,c<=100),如上文描述,第二行是跳舞毯給定的序列,第三行是zyf跳完、輸入的序列,二者的長度都不大於1000,只包含大小寫字母。
Output
  每組數據輸出一行,最少修改時間。
Sample Input
1 2 3
LDDD
DDDR
7 1 3
LDDR
LZRZDD
Sample Output
3
8

算法說明:算法

又是一道典型的動態規劃題目,假設機器給定的序列是S1,zyf輸入的序列爲S2。序列S1的長度爲len1,序列S2的長度爲len2,那麼假設經過S2變換到序列S1須要的代價是res[len1][len2], 那麼能夠想到res[len1][len2]必定是min{ res[len1][len2-1]+a , res[len1+1][len2]+b , S1[len1-1]==S2[len2-1]?S1[len1-1][len2-1]:S1[len1-1][len2-1]+c },那麼遞歸會重複計算,效率不高,所以使用動態規劃。spa

 

代碼以下:code

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 
 6 int res[1010][1010] ;
 7 int len1 , len2 ;
 8 
 9 
10 int main()
11 {
12     int a , b , c ;
13     while(cin >> a >> b >> c){
14         string s1 , s2 ;
15         cin >> s1 >> s2 ;
16         len1 = s1.length() ;
17         len2 = s2.length() ;
18 //        memset(res,0,sizeof(res));
19         int i , j ;
20         for(i = 0 ; i <= len1 ; i++){
21             res[i][0] = i * a ;
22         }
23         for(i = 0 ; i <= len2 ; i++){
24             res[0][i] = i * b ;
25         }
26         for(i = 1 ; i <= len1 ; i++){
27             for(j = 1 ; j <= len2 ; j++){                
28                 int p1 = res[i][j-1] + b ;
29                 int p2 = res[i-1][j] + a ;
30                 int p3 ;
31                 if(s1[i-1] == s2[j-1]){
32                     p3 = res[i-1][j-1] ;
33                 }else{
34                     p3 = res[i-1][j-1] + c ;
35                 }
36                 int min = p1 < p2 ? p1 : p2 ;
37                 res[i][j] = min < p3 ? min : p3 ;
38             }
39         }
40         cout << res[len1][len2] << endl;
41     }
42     return 0 ;
43 }
相關文章
相關標籤/搜索