poj 2033 Alphacode (dp)

Alphacode

Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 13378   Accepted: 4026

Description

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 500 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 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 long variable.

Sample Input

25114
1111111111
3333333333
0

Sample Output

6
89
1

分析:因为题目给的都是正常数据,所以不会出现两个0连在一起的情况。这道题要十分注意有0出现的情况(因为0 WA了好几次。。,我本来以为题目中会有非合法的情况出现的,比如1002,WA之后还把02当做一个数也试了试,依旧WA。。看了discuss的测试数据才知道这么想是错的),当有0出现时,说明前面的那个数肯定是1或2,可以和这个0配对,所以result[i] = result[i - 2]。对于非0 的情况,如果前面的数是1,则当前的数可以单独作为一个数存在(result[i - 1]种情况),也可以和前面的1配对存在(result[i - 2]种情况),当前面的数是2,当前的数大于0小于7时也是这种情况。否则的话就是只能当前的数作为单独的一个数存在了,有result[i - 1]种情况。

Java AC 代码

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        String str = "";
        char[] input;
        long[] result;
        while(!(str = sc.next()).equals("0")) {
            input = str.toCharArray();
            int len = input.length;
            result = new long[len];
            result[0] = 1;
            if(len == 1) {
                System.out.println(1);
                continue;
            }

            if(input[1] == ‘0‘)
                result[1] = 1;
            else if(input[0] == ‘1‘ || input[0] == ‘2‘ && input[1] < ‘7‘)
                result[1] = 2;
            else
                result[1] = 1;

            for(int i = 2; i < len; i++) {
                if(input[i] == ‘0‘)
                    result[i] = result[i - 2];
                else if(input[i - 1] == ‘1‘ || input[i - 1] == ‘2‘ && input[i] < ‘7‘)
                    result[i] = result[i - 2] + result[i - 1];
                else
                    result[i] = result[i - 1];
            }
            System.out.println(result[len - 1]);
        }
    }
}
时间: 2024-08-05 14:55:31

poj 2033 Alphacode (dp)的相关文章

poj 3342(树形dp)

题意:在一个公司中要举办一个聚会,每一个员工有一个奉献值.为了和谐规定直接上下级不能一起出席.让你找出奉献值之和最大为多少. 思路:dp[v][1]表示当前结点选,能获得的最大奉献值,dp[v][0]表示当前节点不选能获得的最大奉献值.状态转移: dp[v][0] = max(dp[v][0], ∑max(dp[x][1], dp[x][0]))x为直接儿子 dp[v][1] = max(dp[v][1], ∑dp[x][0] + vex[v]) 最后答案是max(dp[root][0], dp

poj 2151 概率dp

//poj 2151 概率dp 1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm" 5 using namespace std; 6 double dp[33][33]; 7 int M, T, N; //problem, team, least 8 double p[1010][33]; 9 int mai

POJ 2250 Compromise (DP,最长公共子序列)

Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6440 Accepted: 2882 Special Judge Description In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria must be fulfille

poj 1947(树形dp)

题意:一棵树上问你最少切掉几条边使得能分割出一个结点数正好为k的子树. 思路:dp[i][j]表示以i为根切掉j个结点最少要几条边. dp[v][j] = min(dp[v][j], dp[v][j-k] + dp[x][k]); 代码如下: 1 dp[v][j] = min(dp[v][j], dp[v][j-k] + dp[x][k]); 2 } 3 } 4 } 5 } 6 } 7 return vex[v]; 8 } 9 10 int main() 11 { 12 // freopen("

POJ 2486 树形DP

有一颗苹果树,每个节点上面有很多苹果,从一个节点到另外一个可以到达的节点花费1步,求k步最多能吃到多少苹果,起始点为1,可以不回到起始点. 这是典型的回溯型树状dp. dp[i][j][0]代表以i为根节点的子树最多j步后回到i能吃到的最多的苹果, dp[i][j][1]代表以i为根节点的子树最多j步后不回到i节点最多能吃到的子树.那么状态转移就分三步了. (1)dp[i][j+2][0] = max(dp[i][j+2][0], dp[i][j-k][0]+dp[son][k][0]); (2

POJ 2411 插头DP

1 //插头DP,算是广义路径的吧. 2 /* 3 我是这样想的,定义填数的为0,未填的为1.然后,初始自然是(0,0).我还定义了整个棋盘的状态,不知是否多此一举. 4 这样,把轮廓线上的格子状态记录.当(I,J)上方的格子为空,必定要填一个竖的.当左边格子为空,当前可填一个横的,也可不填. 5 当左边格子不为空,当前格子必为空...AC. 6 */ 7 8 #include <iostream> 9 #include <cstdio> 10 using namespace st

poj 1458 动态规划DP

//  poj 1458  zoj 1733  最长公共子序列  DP #include <iostream>#include <string.h>#define N 1005using namespace std ;char  s1[N],s2[N];   int dp[N][N];int max(int a,int b)   {    return a>b ? a : b ;  }void f(int n,int m){   int i,j;    for (i=0; i

POJ 1925 Spiderman(DP)

题目链接 题意 : Spiderman从最左边的楼通过将蛛丝粘到后边的某座楼顶,然后荡过去,接着发射蛛丝荡过去,直到到达最后的楼.问最少发射几次蛛丝. 思路 :从横坐标 j 能跳过建筑物 i 需满足: (p[i].x - j)*(p[i].x - j) <= p[i].y*p[i].y  - (p[i].y - p[0].y)*(p[i].y-p[0].y). 从横坐标 j 经建筑物 i 后 到达横坐标 2 * p[i].x - j. 所以状态转移方程是: dp[2 * p[i] .x- j]

POJ 3701 概率DP

给定2^n 支足球队进行比赛,n<=7. 队伍两两之间有一个获胜的概率,求每一个队伍赢得最后比赛的概率是多少? 状态其实都是很显然的,一开始觉得这个问题很难啊,不会.dp[i][j] 表示第i支队伍赢得前j轮比赛的概率.(这个题目处理区间的时候比较恶心,小心点即可). 1:   2: #include <iostream> 3: #include <cstdio> 4: #include <cstring> 5: #include <map> 6: #