字母转换-动态规划
问题描述
规定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];
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律