算法练习笔记(十一)— 动态规划之分解问题

许久没更新算法作业,实在惭愧,会在最近几天一起补全

动态规划的实质实际就是不断地打破问题为一个又一个的子问题,和递归不同的是,它避开了重复计算的部分,成就了一个高效的算法。

然而动态规划常常没有固定的模板,稍一不注意就会发生维数灾。

今天的leetcode题目是这样的:

地址:https://leetcode.com/problems/count-numbers-with-unique-digits/#/description

题目:Count Nums with unique Digits

题目描述:

Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n.

Example:
Given n = 2, return 91. (The answer should be the total numbers in the range of 0 ≤ x < 100, excluding [11,22,33,44,55,66,77,88,99])

即给一个非负数n,并在0 ~ 10^n中找出组成数字均不同的数的个数x

因为属于动态规划的问题,理所当然我们就会想到将所得解建立在前面解的结果的基础之上的思路,于是观察这些数字

发现原来在后面的数字之中,前面所得的数字其实是包含其中的,因此大可不必重复计算,则所得的结果应该为(新增数个数 + 之前已有个数

即f(n)  = (10 - n + 1)(f(n - 1) - f(n - 2)) + f(n - 1) 可化简为 f(n) = (12 - n)* f(n - 1) - (11 - n) * f(n - 2)

我们可以轻松得知f(1) = 10, f(0) = 0,则之后的结果便可推知

class Solution {
public:
    int countNumbersWithUniqueDigits(int n) {
        if(n > 9)n = 9;
        return NumsCount(n);
    }
    
    int NumsCount(int n){
        if(n == 0)return 1;
        if(n == 1)return 10;
        else
        return (12 - n) * NumsCount(n - 1) - (11 - n) * NumsCount(n - 2);
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值