动态规划-数位DP
什么是数位DP
数位dp是与数字相关的一类计数问题。这这类问题中,一般给定一些限制条件,求满足第
本文主要讲述如何解决 求区间
为什么要用数位dp
对于上述问题,如果只使用简单的暴力,时间复杂度为
如果采用
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int num[N];
int dfs(int len, bool limit, bool lead, /*一些参数记录是否符合条件*/) {
//limit表示当前的最高数是否有限制 lead表示前导0
if(len == 0) return sum;
int ans = 0;
int maxx = limit ? num[len]:9;
for (int i = 0; i <= maxx; i++) {
ans += dfs(len-1, limit&&(i==maxx), lead||i, /*一些参数*/);
}
return ans;
}
int work(int x, int i) {
int len = 0;
while (x) {
num[++len] = x%10;
x /= 10;
}
memset(f, -1, sizeof(f));
return dfs(len, 1, 0, i, 0);
}
int main() {
int a, b;
scanf("%d %d", &a, &b);
for (int i = 0; i <= 9; i++) {
printf("%d ", work(b, i) - work(a-1, i));
}
return 0;
}
详解
可这样时间复杂度仍旧不尽人意。
怎么用数位dp
我们观察到,有很多等价的状态被重复遍历。举个例子
代码如下
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
int a, b;
int num[N],f[N][N];
int dfs(int len, bool limit, bool lead, /*一些参数记录是否符合条件*/) {
if(len == 0) {
if(!lead) return 0;
return 1;
}
if(!limit&& /*根据题目自定参数*/) return f[][];
int ans = 0;
int maxx = limit ? num[len]:9;
for (int i = 0; i <= maxx; i++) {
ans += dfs(len-1, limit&&(maxx==i), lead||i, /*一些参数记录是否符合条件*/);
}
if(!limit&&lead) f[len][last] = ans;
return ans;
}
int solve(int x) {
memset(f, -1, sizeof(f));
int len = 0;
while (x) {
num[++len] = x%10;
x /= 10;
}
if(len==0) return 0;
return dfs(len, 1, 0, -2);
}
int main() {
scanf("%d %d", &a, &b);
printf("%d", solve(b)-solve(a-1));
return 0;
}
参考资料
本文来自博客园,作者:Wh1sky,转载请注明原文链接:https://www.cnblogs.com/wh1sky/p/18057033
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!