【C语言 每日一题】SOJ 1001 Alphacode

问题

看这里

题解

看到这个题,应该很容易就想到动态规划啦!我们假设对一串长度为 n 的标准输入 s 能得到解码种数为 dp[n]。根据题意,应该有以下关系成立:

  1. 如果 s[n-1] 不能够与 s[n-2] 组合,dp[n] = dp[n - 1];
  2. 反之,dp[n] = dp[n - 1] + dp[n - 2]。
  3. 这里还有个小陷阱,对于能组合的 s[n-1]s[n-2] 来说,如果 s[n-1] 为 0 的话,则 dp[n] = dp[n - 2];

举个栗子,对于输入 123,求 dp[3]。
由于 2 能与 3 组合,所以产生的解码方式总数就为 dp[2](不组合)+ dp[1](组合)。

有了思路,代码就很简单啦!

代码

#include <stdio.h>
#include <string.h>

#define LIMIT 5000

long decode(const char str[]);

int main() {

  char input[LIMIT];

  while (scanf("%s", input) && input[0] != '0')
    printf("%ld\n", decode(input));

  return 0;
}

long decode(const char str[]) {
  int len = strlen(str);
  long dp[len];
  int i;

  dp[0] = 1;

  for (i = 1; i < len; ++i)
    if (str[i] == '0' && (str[i - 1] == '1' || str[i - 1] == '2'))
      if (i > 1)
        dp[i] = dp[i - 2];
      else
        dp[i] = 1;
    else if (str[i - 1] == '1' || str[i - 1] == '2' && str[i] <= '6')
      if (i > 1)
        dp[i] = dp[i - 1] + dp[i - 2];
      else
        dp[i] = dp[i - 1] + 1;
    else
      dp[i] = dp[i - 1];

  return dp[i-1];
}

很明显,这个解法的时间复杂度为 O(n),空间复杂度也为 O(n)。但仔细观察你会发现,这里只用到了 dp[i]dp[i-1]dp[i-2],多用的空间是完全没有必要的!所以,你可以这么写:

long decode_mini(const char str[]) {
  long current, prev, pprev;
  int i;

  pprev = prev = current = 1;
  for (i = 1; str[i] != '\0'; ++i) {
    if (str[i] == '0')
      current = pprev;
    else if (str[i - 1] == '1' || str[i - 1] == '2' && str[i] <= '6')
      current = prev + pprev;
    else
      current = prev;

    pprev = prev;
    prev = current;
  }

  return current;
}

今日阅读笔记

C语言 操作符优先级

C Operator Precedence

注意:
1. ~ 和 ! 操作符比 & | ^ 优先级高多了(明明都是位操作符~)
2. && 优先级比 || 高
3. 赋值操作符优先级只比 ,
4. & | ^ 的优先级没有比较操作符(==,>=,<=)高

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值