【New deal】poj2033 Alphacode

      好久不写点东西了,博客里都长草了XD~

      今天发道水题先练练手…

      题目是poj的2033(http://poj.org/problem?id=2033),一道很水的动归。题目如下。 

【题目描述】
一对valentine聚在一起,商讨用一种加密方法传递信息以避免学校发现。
Girl说,我们就用这样一种传统的方法,A对应1,B对应2,这样我们的话就变成了一个数串,想法如何?
Boy说,你真笨~就拿“Te amo”来说,按照你的办法翻译成20511315,这样我可能想成“Tekco”或者
“Teaacae”,我怎么知道你说的是什么?就别的数串来说,答案可能成千上万。
Girl不信,她要给你一个数串,让你算算一共有多少种答案。
【输入格式】
输入可能有多个数据,每组数据以换行隔开,文件以一个0结束。(关于这里更准确的信息请参见原题)
【输出格式】
对于每个数据输出相应的答案数,以换行隔开。
【样例输入】
25114
1111111111
3333333333
0
【样例输出】
6
89
1

这题是一道很显然的DP。用f[i]记录到i位的答案数,从左到右按位进行计算:

1.  串长为1,答案数为1。

    否则:

2.  如果这一位为0,那么f[i]=f[i-2],因为它和s[i-1]只能构成一种情况。

3.  如果这一位不为0,则令k=s[i-1]*10+s[i],如果k∈[1,26]则f[i]=f[i-1]+f[i-2],因为s[i]既可以自己作为一个一位数,也可以和s[i-1]作为一个两位数出现;反之,f[i]=f[i-1],因为       它只能自己的构成一个一位数。

4.  f[length(s)]即为解。

    思路很简单,但是我的Pascal代码就是过不去…因为解可能很大,在长度到一定值的时候f数组中的值就会出问题。这种情况在c++上也会出现,但是c++的代码就过了…

    我不知道是Pascal和c++的代码在读入的时候不一样还是在越界的处理上不一样,如果你知道为什么,请联系我,不胜感激~

注意:1. 单个数据的长度可能超过一行。

        2. 最好用64位存储…

        3.最好用c编写…

    下面附上两段代码。

未过代码(Pascal):

program poj2033;
  var
    f:array[0..50000]of longint;
    s:ansistring;
  procedure dynamicp(x:longint);
    var
      i,j:longint;
      k:integer;
    begin
      if x=1 then
        begin
          writeln('1');
          exit;
        end;
      if x=2 then
        begin
          if s[2]<>'0' then
            writeln('2')
            else writeln('1');
          exit;
        end;
      f[0]:=1;
      f[1]:=1;
      for i:=2 to x do
        begin
          if s[i]='0' then f[i]:=f[i-2]
            else begin
                   k:=(ord(s[i-1])-ord('0'))*10+ord(s[i])-ord('0');
                   if (k>0)and(k<27) then f[i]:=f[i-2]+f[i-1]
                     else f[i]:=f[i-1];
                 end;
        end;
      writeln(f[x]:0:0);
    end;

  begin
    readln(s);
    while s<>'0' do
      begin
        dynamicp(length(s));
        readln(s);
      end;
  end.

参考代码(c++,来源:http://blog.sina.com.cn/s/blog_6635898a0100h9rn.html):

#include <iostream>
using namespace std;
const int MAXN = 50000;
int main()
{
      __int64 dp[MAXN];
      char s[MAXN];
      while(scanf("%s", s + 1) != EOF) {
           int len = strlen(s + 1);
           if(len == 1 && s[1] == '0') break;
           dp[0] = dp[1] = 1;
           for(int i = 2; i <= len; i++) {
                if(s[i] != '0') {
                      dp[i] = dp[i - 1];
                      int num = (s[i - 1] - '0') * 10 + (s[i] - '0');
                      if(num >= 11 && num <= 26) dp[i] += dp[i - 2];
                }else{
                      if(s[i - 1] == '0') dp[i] == dp[i - 1];
                      else if(s[i - 1] == '1' || s[i - 1] == '2') dp[i] = dp[i - 2];
                }
           }
           printf("%I64d\n", dp[len]);
      }
      return(0);
}

本文地址:http://www.cnblogs.com/saltless/archive/2011/05/29/2061959.html

(Saltless原创,转载请注明出处)

posted on 2011-05-29 11:58  saltless  阅读(570)  评论(0编辑  收藏  举报

导航