POJ 2033 DP

Alice and Bob need to send secret messages to each other and are discussing ways to encode their messages:

Alice: “Let’s just use a very simple code: We’ll assign ‘A’ the code word 1, ‘B’ will be 2, and so on down to ‘Z’ being assigned 26.”

Bob: “That’s a stupid code, Alice. Suppose I send you the word ‘BEAN’ encoded as 25114. You could decode that in many different ways!”

Alice: “Sure you could, but what words would you get? Other than ‘BEAN’, you’d get ‘BEAAD’, ‘YAAD’, ‘YAN’, ‘YKD’ and ‘BEKD’. I think you would be able to figure out the correct decoding. And why would you send me the word ‘BEAN’ anyway?”

Bob: “OK, maybe that’s a bad example, but I bet you that if you got a string of length 5000 there would be tons of different decodings and with that many you would find at least two different ones that would make sense.”

Alice: “How many different decodings?”

Bob: “Jillions!”

For some reason, Alice is still unconvinced by Bob’s argument, so she requires a program that will determine how many decodings there can be for a given string using her code.

Input

Input will consist of multiple input sets. Each set will consist of a single line of at most 5000 digits representing a valid encryption (for example, no line will begin with a 0). There will be no spaces between the digits. An input line of ‘0’ will terminate the input and should not be processed.

Output

For each input set, output the number of possible decodings for the input string. All answers will be within the range of a 64 bit signed integer.

Example
Input:

25114
1111111111
3333333333
0

Output:

6
89
1
———————————————————————在此寄托我为弱鸡的理由——————————————————————————
  这道题是道dp题,很明显(正经脸)
  因为当每个数字贴上去的时候都有两种状态:1:和之前的数字组合,2:单个存在。其中1是要看前后两个数字状态的,所以把前面的结果记录以后按次序进行判断可得答案。状态如下:
  
  其中需要特殊讨论的状况是0,因为题目中说了给出的格式全为合法格式,0本身不能作为单个字母出现,也就是说0前面必然跟着的是一个合法的字符,也就是说,这种情况是属于前面说的1的单个组合,而不存在单个存在这种状况。
  0所带来的影响还有对于0后面一个字符的讨论,0后面的字符当然不可能和0组合,所以是只能单个存在而不能组合的情况。这里需要特判,因为按照之前那个是不是为26之内的判定方法来说的话一定结果是6.
  然后根据图上的样例我们可以知道,组合的情况需要查看两步前的状况,单个存在的情况就是把前一步的状态给继承。变成dp的伪代码就是:
  if(可组合)dp[i]=dp[i-1]+dp[i-2];
  else dp[i]=dp[i-1];
  以上。
  快要结束的时候推出来的一点点,但是估计到最后还是要被0的特殊状态给坑到了。
  以及以后感觉是dp的话找个样例推一下感觉有奇效。
_______________________________________code______________________________________________________________

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<climits>
#include<map>
#include<stack>
#include<cmath>
#define file_in freopen("in.txt","r",stdin)
#define MAX 200000
#define maxn 5005
using namespace std;
#define LL long long
#define FF(x,y) for(int i=x;i<y;i++)
int check(char a, char b)
{
    int num = (a - '0') * 10 + (b - '0');
    if (num < 27 && num>0)
        return 1;
    else
        return 0;
}
int main()
{
    string num;
    while (cin >> num)
    {

        if (num == "0")break;
        vector<LL>dp(num.size() + 1, 1);
        for (int i = 1; i < num.size(); i++)
        {
            LL tar = num[i] - '0';
            if (tar == 0)
                dp[i + 1] = dp[i - 2 + 1];//因为题目中保证过不出现超出格式外的情况,所以不用考虑0是否和之前的数字匹配
            else
            {
                if (num[i - 1] - '0' == 0)dp[i + 1] = dp[i - 1 + 1];
                else if (check(num[i - 1], num[i]))dp[i + 1] = dp[i - 1 + 1] + dp[i - 2 + 1];
                else dp[i + 1] = dp[i - 1 + 1];
            }
        }
        printf("%lld\n", dp[num.size()]);
    }
}
/*
Input:

25114
1111111111
3333333333
0

Output:

6
89
1
*/

转载于:https://www.cnblogs.com/stultus/p/6476488.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值