BZOJ 1833: [ZJOI2010]count 数字计数( dp )

dp(i, j, k)表示共i位, 最高位是j, 数字k出现次数. 预处理出来.

差分答案, 对于0~x的答案, 从低位到高位进行讨论

------------------------------------------------------------------------------

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 16;

const int N = 10;

const int L = 14;

ll dp[maxn][maxn][maxn], ans[2][maxn];

void init() {

memset(dp, 0, sizeof dp);

ll power = 1;

for(int i = 0; i < N; i++) dp[1][i][i] = 1;

for(int i = 2; i < L; i++) {

power *= 10LL;

for(int j = 0; j < N; j++) {

dp[i][j][j] += power;

for(int k = 0; k < N; k++)

for(int l = 0; l < N; l++)

dp[i][j][l] += dp[i - 1][k][l];

}

}

}

// [0, x]

void work(ll x, int p) {

if(x < 0) return;

int s[maxn], n = 0;

if(!x) s[++n] = 0;

for(; x; x /= 10) s[++n] = x % 10;

ll cnt = 1, power = 1;

for(int i = 1; i <= n; i++) {

ans[p][s[i]] += cnt;

cnt += power * s[i];

power *= 10LL;

for(int j = (i == n && i != 1); j < s[i]; j++)

for(int k = 0; k < N; k++) ans[p][k] += dp[i][j][k];

for(int j = (i != 2); j < N; j++)

for(int k = 0; k < N; k++)

ans[p][k] += dp[i - 1][j][k];

}

}

int main() {

init();

ll a, b; cin >> a >> b;

work(a - 1, 0); work(b, 1);

for(int i = 0; i < N; i++) {

if(i) putchar(‘ ‘);

printf("%lld", ans[1][i] - ans[0][i]);

}

return 0;

}

------------------------------------------------------------------------------

1833: [ZJOI2010]count 数字计数

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 1995  Solved: 880
[Submit][Status][Discuss]

Description

给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。

Input

输入文件中仅包含一行两个整数a、b,含义如上所述。

Output

输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。

Sample Input

1 99

Sample Output

9 20 20 20 20 20 20 20 20 20

HINT

30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。

Source

Day1

时间: 2024-10-12 00:50:53

BZOJ 1833: [ZJOI2010]count 数字计数( dp )的相关文章

[BZOJ 1833] [ZJOI2010] count 数字计数 【数位DP】

题目链接:BZOJ - 1833 题目分析 数位DP .. 用 f[i][j][k] 表示第 i 位是 j 的 i 位数共有多少个数码 k . 然后差分询问...Get()中注意一下,如果固定了第 i 位,这一位是 t ,那么数码 t 的答案是要加一个值的(见代码). 代码 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmat

BZOJ 1833 ZJOI2010 count 数字计数 数位DP

题目大意:求[a,b]间所有的整数中0~9每个数字出现了几次 令f[i]为i位数(算前导零)中每个数出现的次数(一定是相同的,所以只记录一个就行了) 有f[i]=f[i-1]*10+10^(i-1) 然后照例十进制拆分 其中计算[0,999...9]的时候要从1~9枚举最高位,然后其余位调用f[i-1]即可 剩余部分已知位直接乘,未知位调用f[i] #include<cstdio> #include<cstring> #include<iostream> #includ

bzoj 1833: [ZJOI2010]count 数字计数【数位dp】

非典型数位dp 先预处理出f[i][j][k]表示从后往前第i位为j时k的个数,然后把答案转换为ans(r)-ans(l-1),用预处理出的f数组dp出f即可(可能也不是dp吧--) #include<iostream> #include<cstdio> using namespace std; long long l,r,t[25]; struct dp { long long a[15]; dp operator + (dp x) { dp r; for(int i=0;i&l

bzoj 1833: [ZJOI2010]count 数字计数

1 #include<cstdio> 2 #include<iostream> 3 #define ll long long 4 using namespace std; 5 struct data 6 { 7 ll s[10]; 8 }a[15][10],sum1,sum2; 9 ll f[18],l,r; 10 data operator +(data a1,data a2) 11 { 12 data t; 13 for(int i=0;i<=9;i++) 14 t.s[

1833: [ZJOI2010]count 数字计数

1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 2951  Solved: 1307[Submit][Status][Discuss] Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a.b,含义如上所述. Output 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次.

1833: [ZJOI2010]count 数字计数 - BZOJ

Description给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次.Input输入文件中仅包含一行两个整数a.b,含义如上所述.Output输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次.Sample Input1 99Sample Output9 20 20 20 20 20 20 20 20 20HINT30%的数据中,a<=b<=10^6:100%的数据中,a<=b<=10^12. 首先把这个问题变成f(b)

【BZOJ 1833】 [ZJOI2010]count 数字计数

1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 1697 Solved: 753 [Submit][Status][Discuss] Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a.b,含义如上所述. Output 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次.

bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)

1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义f[i][j][k]表示若前i个位置有k个j的此时的全局方案数,然后就可以记忆化搜索了(具体看代码吧) 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath>

数位DP入门:bzoj1833: [ZJOI2010]count 数字计数

膜拜了一下蔡大神....然后突然想起来一些东西然后就填了一个半年多前的坑= = 人生第一道自己写的数位DP...好吧以前是看题解然后也不知道为什么就过了的>_< 数位DP介绍: http://wenku.baidu.com/link?url=9OS5Ybpw5wx00ahrH8ED2oyIlR1uWwrxT8N4pEg27GgBt2T2hLe4sd_h1rmpY7P0HmeHIEDw9h6_K98dPhhjoMhD2TpKcS8w1X8cC_dkPp_ 接下来是题目地址: http://www