字母转换-动态规划

问题描述

规定1和A对应,2和B对应,3和C对应...26和Z对应,那么一个数字字符串'111'就能转化为'AAA','AK','KA',给定一个只有数字字符组成的字符串str,返回有多少种转化结果。

思路

base-case:如果'0'单独出现,则之前的决定不成立,此方法不成立;
如果能走到最后,则前面的决定算一种方法;
在中间过程中会遇到两种选择:

  • 一种是单转一个字符
  • 一种是与后面一个字符组成二位数(在符合条件下)
    最终总的方法是两者合理的方法数之和。

代码

#include <iostream>

using namespace std;
int way1(char str[], int N);
int way2(char str[], int N);
//str[0..i]已经确定
//返回str[i...]之后的个数
int process(char str[], int i, int N);
int main() {
    char str[6] = {'1', '2', '2', '3', '5', '2'};
    cout << way1(str, 6) << endl;
    cout << way2(str, 6) << endl;
    return 0;
}
int way1(char str[], int N) {
    return process(str, 0, N);
}
//str[0..i]已经确定
//返回str[i...]之后的个数
int process(char str[], int i, int N) {
    if(i == N) {
        return 1;
    }
    if(str[i] == '0') {
        return 0;
    }
    //方法一i位置单转
    int res = process(str, i + 1, N);
    //方法二i与i+1位置结合
    if(i + 1 < N && (str[i] - '0') * 10 + (str[i + 1] - '0') < 27) {
        res += process(str, i + 2, N);
    }
    return res;
}
int way2(char str[], int N) {
    int dp[7];
    dp[6] = 1;
    for(int i = N - 1; i >= 0; i--) {
        if(str[i] == '0') {
            dp[i] = 0;
        } else {
            //方法一i位置单转
            int res = dp[i + 1];
            //方法二i与i+1位置结合
            if(i + 1 < N && (str[i] - '0') * 10 + (str[i + 1] - '0') < 27) {
                res += dp[i + 2];
            }
            dp[i] = res;
        }
    }
    return dp[0];
}

posted @   sakuzeng  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示