soj1001算法分析

题目简单描述: 给定一个长数串,输出可能的字母串解个数。(A对应1,Z对应26)

样例输入:25114

样例输出:6

样例解释:可能的字母串解:YJD、YAAD、YAN、BEJD、BEAAD、BEAN

样例输入:33333333

样例输出:1

样例解释:可能的字母串解:CCCCCCCC

Solution1:(递归,结果TLE)

  第一眼看题想到的方法就是递归,逐个字符向后推,直到初态方程。

  设串长度为len,当前处理字符为chr1,下一字符为chr2,前一字符为ch0,则递归方程为:

  if  chr1>‘2‘:

    solution(len)=solution(len-1)

  if  chr1=‘2‘:

    if  chr2<‘7‘:

      solution(len)=solution(len-1)+solution(len-2)

    else:

      solution(len)=solution(len-2)

  if chr1!=‘0‘:

    solution(len)=solution(len-1)+solution(len-2)  

  if chr1=‘0‘:  

    if ch0>‘2‘:

      solution(len)=0

    soltion(len)=solution(len-1)

  边界值:solution(0)=1,solution(1)=1

  结果:本机测试全过,提交结果TLE

Solution2:(动态规划)

  递归时间爆表,考虑从算法优化。分析数字串解码特典,发现具有典型的无后效性与状态性,从而考虑动态规划。

  分析状态转移过程,从末尾数字向前推,假设倒数第i个数字状态下字母可能性为s[i],倒数第i-1个数字状态下字母可能性为s[i-1],倒数第i个数字是str0,倒数第i+1个数字是str1

  则状态转移方程:

    s[i+1]=s[i]+s[i-1]  (str0与str1能形成合法字母)

        =s[i]     (str0与str1不能形成合法字母)

Solution3:(分治)

  注:这是从网上看到的,思维很独特,转之

  首先考虑全由1、2组成的串,则结果只与长度n有关,为斐波那契第n项(这一点很好证明)。然后考虑0与3~9,每发现其中一个数字就作为一个间断,将长数列分成两个子数列,对子数列进行解得求值,然后根据乘法原理得到最后结果

    

soj1001算法分析

上一篇:浅谈模块化编程


下一篇:Linux shell 脚本攻略之根据扩展名切分文件名