• 题解西电OJ (Problem 1005 -跳舞毯)--动态规划


    Description

      zyf不小心得了一种怪病,为了维持一天的精力他必须不停跳动。于是他买了一条跳舞毯,每天跳上几小时。众所周知,跳舞毯是给定一个序列,让你在指定时间踏指定的按钮,但zyf似乎不怎么擅长,为此他写了个外挂,以修改它的输入序列,得到满分!
      这个外挂的厉害之处在于它能等到zyf跳完、输入序列后再进行修改,修改的方式有三种,在任意位置插入、删除或替换一个指令,每次插入需要a时间,删除需要b时间,替换需要c时间,现在zyf想用最短时间去修改他输入的序列得到满分(即与给定序列一样),但这显然已经超过了当前外挂的能力范围,于是只好求助于你,给这外挂写个补丁。

    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 },那么递归会重复计算,效率不高,因此使用动态规划。

    代码如下:

     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 }
  • 相关阅读:
    批处理文件入门
    批处理入门学习地址
    react资料
    React 学习参考资料链接
    Spring boot + jdbc学习笔记
    iOS-升级Https证书报错
    Java-006-循环结构和控制语句详解(while, dowhile ,for ,switch)
    Java-005-运算符详解
    Java-004-变量类型和修饰符详解
    Java-001简介和基础语法[类方法、实例方法、public class 与 class 区别](第一个Java程序)
  • 原文地址:https://www.cnblogs.com/liucheng/p/3683653.html
Copyright © 2020-2023  润新知