Acwing 59. 把数字翻译成字符串 计数类DP

原题连接:
https://www.acwing.com/problem/content/description/55/

LeetCode连接:
https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/

这是原本按照我的状态表示和状态转移写的代码:

class Solution {
public:
    int getTranslationCount(string s) {
        /*
            计数类DP,是怎么想到用f[i]表示的呢??
            f[i]表示前i个字母有多少种情况。
            分为两种情况:
            1. 只考虑s[i]
            2. 考虑s[i - 1] 和 s[i], 但是此时这俩字母组成的二位数需要满足
            10<= <=25 
            f[i]等于这两种情况相加。
            处理边界情况:
            f[0] = 1
            答案:
            f[n - 1]
        */
        int n = s.size();
        if(n == 1) return 1;
        vector<int> f(n + 1);
        // 先预处理好f[0]和f[1]
        f[0] = 1;
        f[1] = 1;
        int t = (s[0] - '0') * 10 + s[1] - '0';
        if(10 <= t && t <= 25) f[1] += 1;

        for (int i = 2; i < n; i ++ ){
            f[i] = f[i - 1];
            int t = (s[i - 1] - '0') * 10 + s[i] - '0';
            if(10 <= t && t <= 25) f[i] += f[i - 2];
        }
        
        return f[n - 1];
    }
};

这是y总,处理过后的代码。为了防止i - 2越界,他直接加了一个偏移量,向右偏移了一位
f[i+1]表示前i个数的计数情况。这样就不用单独处理f[1]了。

class Solution {
public:
    int getTranslationCount(string s) {
        /*
    	f[1]和f[0]都是1,不过这样f[0]不好解释了,不容易理解。在这种情况下,为了更好地解释为啥f[0] = 1.
    	 问题:为什么一个数字都没有的方案数是1?是凑出来的。
		 f[0]代表翻译前0个数字的方法数,这样的状态定义其实是没有实际意义的,但是f[0]的值				  需要保证边界是对的,即f[1]和f[2]是对的。比如说,翻译前1个数只有一种方法,将其单独翻译,   即f[1] = f[1 - 1] = 1。翻译前两个数,
        如果第1个数和第2个数可以组合起来翻译,那么f[2] = f[1] + f[0] = 2 ,否则只能单独翻译第2个数,即f[2] = f[1] = 1。因此,在任何情况下f[0]取1都可以保证f[1]和f[2]是正确的,所以f[0]应该取1
        */
        int n = s.size();
        vector<int> f(n + 1);
        f[0] = 1;
        for (int i = 1; i <= n; i ++ ){
            f[i] = f[i - 1];
            if(i > 1){
            // 然后这里也是用的f[i - 2] 和 f[i - 1]
                int t = (s[i - 2] - '0') * 10 + s[i - 1] - '0';
                if(10 <= t && t <= 25) f[i] += f[i - 2];
            }
        }
        // 所以最后返回的也是f[n]
        return f[n];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值