将字母A-Z编码,A为1,B为2,……依此类推,Z为26;则ABC编码为123。但是反向解码时,解码结果不唯一,比如123可以解码为 1-2-3:ABC,解码为12-3:LC,解码为1-23:AW(注意,127不能解码为1-27,因为范围只能为1-26)。

 现给出一组编码后的数字串,让你求该数字串可以有几种解码方式(上例中,123对应着3种解码方式)。问题输入将保证其为一个合法的数字串。比如100是 一个不合法的数字串,因为0或者00不代表一个字母;此外01不能视为1。

  Sample Input

25114 1111111111 3333333333

Sample Output

6 89 1

 



1 /*
2 * zoj 2022 来自大黄dp分类.. 一维dp..有点水,有点郁闷的地方就是0的处理...
3 * 递推公式:
4 * dp[i][j] = dp[i][j-2]; 当num[i] == 0;
5 * dp[i][j] = dp[i][j-1]+dp[i][j-2]; num[i] 和num[i-1]满足大于0小于27;
6 * dp[i][j] = dp[i][j-1]; 当num[i]和num[i-1]满足不了大于0小于27的情况时;
7 * zjy 2011 03 09
8 * */
9 #include <stdio.h>
10 #include <string.h>
11 #define MAX 50000
12 int judge(char a,char b)
13 {
14 if(a=='0')
15 return 0;
16 if(a>'2')
17 return 0;
18 if(a=='2'&&b>'6')
19 return 0;
20 return 1;
21 }
22 int main(void)
23 {
24 char num[MAX];
25 int dp[MAX];
26 while (scanf("%s",num) != EOF && num[0]!='0')
27 {
28 int len = strlen(num);
29 memset(dp,0,sizeof(dp));
30 dp[0]=1;
31 for (int i=1;i<len;i++)
32 {
33 if(num[i]=='0')
34 { if(i>=2)
35 dp[i] = dp[i-2];
36 else
37 dp[i] = 1;
38 }
39 else if(judge(num[i-1],num[i])) //能够组成26以内的数;
40 {
41 if(i>=2)
42 dp[i]=dp[i-1]+dp[i-2];
43 else
44 dp[i] = dp[i-1]+1;
45 }
46 else
47 dp[i] = dp[i-1];
48 }
49 printf("%d\n",dp[len-1]);
50 }
51 return 0;
52 }


 


作者:​​火星十一郎​

本文版权归作者火星十一郎所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.