【算法基础:动态规划】5.4 数位统计DP(计数问题)(数位DP)

news/2024/10/23 17:36:30/

文章目录

  • 例题:338. 计数问题
    • 解法1——转换成1067. 范围内的数字计数,数位DP模板
    • 解法2——分情况讨论(TODO,还没理解)
  • 相关链接⭐

例题:338. 计数问题

https://www.acwing.com/problem/content/340/
在这里插入图片描述

解法1——转换成1067. 范围内的数字计数,数位DP模板

解法来自:【算法】数位DP

import java.util.*;public class Main {static int[][] memo;static char[] s;static int t;public static void main(String[] args){Scanner sc = new Scanner(System.in);while (true) {int a = sc.nextInt(), b = sc.nextInt();if (a == 0 && b == 0) return;for (int i = 0; i <= 9; ++i) {System.out.print((a > b? count(a, i) - count(b, i): count(b, i) - count(a, i)) + " ");}System.out.println();}}// 计算1~n中,数字x出现的次数static int count(int n, int x) {s = Integer.toString(n).toCharArray();t = x;int m = s.length;memo = new int[m][m];for (int i = 0; i < m; ++i) Arrays.fill(memo[i], -1);return dfs(0, true, false, 0);}static int dfs(int i, boolean isLimit, boolean isNum, int cnt) {if (i == s.length) return cnt;if (!isLimit && isNum && memo[i][cnt] != -1) return memo[i][cnt];int res = 0;if (!isNum) res = dfs(i + 1, false, false, 0);int up = isLimit? s[i] - '0': 9;for (int d = isNum? 0: 1; d <= up; ++d) {res += dfs(i + 1, isLimit && d == up, true, cnt + (d == t? 1: 0));}if (!isLimit && isNum) memo[i][cnt] = res;return res;}
}

解法2——分情况讨论(TODO,还没理解)

https://www.acwing.com/video/323/
https://www.acwing.com/activity/content/code/content/64211/

我们需要实现一个函数 count(int n, int x) 求 1 ~ n 中数字 x 出现的次数。

分情况讨论 是思路中最重要的部分。

#include <iostream>
#include <algorithm>
#include <vector>using namespace std;const int N = 10;/*001~abc-1, 999abc1. num[i] < x, 02. num[i] == x, 0~efg3. num[i] > x, 0~999*/int get(vector<int> num, int l, int r)
{int res = 0;for (int i = l; i >= r; i -- ) res = res * 10 + num[i];return res;
}int power10(int x)
{int res = 1;while (x -- ) res *= 10;return res;
}int count(int n, int x)
{if (!n) return 0;vector<int> num;while (n){num.push_back(n % 10);n /= 10;}n = num.size();int res = 0;for (int i = n - 1 - !x; i >= 0; i -- ){if (i < n - 1){res += get(num, n - 1, i + 1) * power10(i);if (!x) res -= power10(i);}if (num[i] == x) res += get(num, i - 1, 0) + 1;else if (num[i] > x) res += power10(i);}return res;
}int main()
{int a, b;while (cin >> a >> b , a){if (a > b) swap(a, b);for (int i = 0; i <= 9; i ++ )cout << count(b, i) - count(a - 1, i) << ' ';cout << endl;}return 0;
}

相关链接⭐

【算法】数位DP


http://www.ppmy.cn/news/990020.html

相关文章

力扣75——队列

总结leetcode75中队列的算法题解题思路。 上一篇&#xff1a;力扣75——哈希表/哈希集合 以下代码大部分为本人所写&#xff0c;少部分为官方示例代码。 力扣75——队列 1 最近的请求次数2 Dota2 参议院1-2 解题总结 1 最近的请求次数 题目&#xff1a; 写一个 RecentCounter…

PP-Matting: AI高精度图像前景Matting,让抠图轻而易举

分割和Matting的一个重要区别是:分割返回的是像素分类标签,其结果是整型数据;而Matting返回的是属于前景或背景的概率P,从而在前景与背景交互区域产生渐变的效果,使得抠图更加自然。Matting分割模型训练完成后,对于原始图像每个位置上的像素,都将生成一个表示其前景透明…

mysql innodb一些知识点

1、事务和锁的关系&#xff1b; 在MySQL事务中&#xff0c;只要开始了一次事务&#xff0c;就会自动加上一个共享锁&#xff08;Shared Lock&#xff09;。这个锁会在事务结束时自动释放。如果在事务中需要更新某个数据对象&#xff0c;那么MySQL会将该数据对象的共享锁升级为…

Echarts 文字太长用省略号代替

xAxis: [{type: category,data: [materialUserEchartsDate.value[0] ? materialUserEchartsDate.value[0].name : ,materialUserEchartsDate.value[1] ? materialUserEchartsDate.value[1].name : ,materialUserEchartsDate.value[2] ? materialUserEchartsDate.value[2].na…

LeetCode刷题笔记-287题寻找重复数

LeetCode 287 寻找重复数 难度&#xff1a;中等 题目&#xff1a; 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 &#xff0c;返回…

css 四角边框移动效果

块是长宽相等的正方形&#xff0c;大小浏览器分辨率变化而变化利用平移变化translate来时实现边框到达鼠标划到的块&#xff0c;坐标是鼠标滑到块的offsetLeft和offsetTop <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&quo…

shell编程 变量作用域

变量 变量赋值不用$&#xff0c;访问值时用$,赋值时两边不留空格&#xff0c;双引号括起来的变量被值替换{}标记变量开始和结束,变量名区分大小写&#xff0c;所有bash变量的值变量不区分类型&#xff0c;统一为字符串 变量类型 环境变量&#xff0c;子进程可以继承父进程环境…

mysql清除主从复制关系

mysql清除主从复制关系 mysql主从复制中,需要将主从复制关系清除,需要取消其从库角色。这可通过执行RESET SLAVE ALL清除从库的同步复制信息、包括连接信息和二进制文件名、位置。从库上执行这个命令后,使用show slave status将不会有输出。reset slave是各版本Mysql都有的功…