poj3286--How many 0's?(数位dp)

题目链接:点击打开链接

题目大意:给出m和n(n>=m),求m到n区间内的0的个数和。

数位dp,注意统计前缀为0的,和要求的数的高位存在0,对低位的影响。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define LL __int64
LL dp[12][10] , num[12] ;
void init() {
    int i , j , k ;
    memset(dp,0,sizeof(dp)) ;
    dp[1][0] = 1 ;
    for(i = 2 , num[1] = 1; i < 12 ; i++)
        num[i] = num[i-1]*10 ;
    for(i = 2 ; i < 12 ; i++) {
        dp[i][0] = num[i] ;
        for(j = 0 ; j < 10 ; j++) {
            for(k = 0 ; k < 10 ; k++) {
                dp[i][j] += dp[i-1][k] ;
            }
        }
    }
    return ;
}
LL solve(LL x) {
    int a[12] , cnt = 0 , i , j ;
    LL sum , s = 0 ;
    if( x ) sum = 1 ;
    else sum = 0 ;
    while( x ) {
        a[++cnt] = x%10 ;
        x /= 10 ;
    }
    if( !cnt ) a[++cnt] = 0 ;
    for(i = cnt ; i > 0 ; i--) {
        if( a[i] == 0 ) s++ ;
        for(j = 0 ; j < a[i] ; j++) {
            if( i == cnt && j == 0 ) continue ;
            sum += dp[i][j] ;
            sum += s*num[i] ;
        }
        if( i == cnt ) continue ;
        for(j = 1 ; j <= 9 ; j++)
            sum += dp[i][j] ;
    }
    return sum ;
}
int main() {
    LL n , m , ans ;
    init() ;
    while( scanf("%I64d %I64d", &m, &n) != EOF ) {
        if( m == -1 && n == -1 ) break ;
        ans = solve(n) - solve(m) ;
        do{
            if( n%10 == 0 ) ans++ ;
            n /= 10 ;
        }while( n ) ;
        printf("%I64d\n",  ans) ;
    }
    return 0 ;
}

版权声明:转载请注明出处:http://blog.csdn.net/winddreams

poj3286--How many 0's?(数位dp)

时间: 2024-11-08 17:30:01

poj3286--How many 0's?(数位dp)的相关文章

TOJ 2294 POJ 3286 How many 0&#39;s? 数位dp

http://acm.tju.edu.cn/toj/showp2294.html http://poj.org/problem?id=3284 题外话:集训结束,回学校了.在宿舍看了这题,没什么好想法,去洗澡了.转了两个澡堂都特么没开..倒是在路上把这题想了.用回自己的电脑,不得不说苹果的字体渲染,真心高一个等级. 题意:给定两个数a和b,从a写到b,问一共写了多少个0. 分析:当然先转化为求0..a写多少个0.网上有更简单的做法,就是枚举每位作为0,则如果这一位本来是0,左边取1..a-1(不

HDU 3709 数位dp

Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 5276    Accepted Submission(s): 2523 Problem Description A balanced number is a non-negative integer that can be balanced if a pi

Hdu3652B-number数位dp

就是记个余数然后像不要62那样搞 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set>

Hdu3555Bomb数位dp

含有49的 ..就是不要49 ..也可以直接搞 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <

hdu3555 Bomb (记忆化搜索 数位DP)

http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 7316    Accepted Submission(s): 2551 Problem Description The counter-terrorists found a time

【BZOJ-1026】windy数 数位DP

1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5230  Solved: 2353[Submit][Status][Discuss] Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数 Sample I

ac1068 数位dp

这题说的是给了一个区间计算这个区间内 数各个数字之和为S的最小数 其实这个题目首先可以求出[A,B]内所有数字之和为S的数的个数cnt,然后观察一下,不难发现,最小的那个数字肯定是在 cnt=1的时候对应的区间端点.由于具有严格的单调性,即随着区间长度的延长,满足条件的cnt肯定会越来越多.所以先可以数位dp求出cnt.然后二 分区间,若cnt>=1,那么说明[A,B]间肯定不止一个符合条件的数字.注意题目要求最小的数字,所以二分区间右端点即可,不要二分左端.这是 主要思路.其实就是个裸的数位d

【数位DP】bnuoj 52813 J. Deciphering Oracles

http://acm.bnu.edu.cn/v3/contest_show.php?cid=9208#problem/J [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 ll N,K; 5 ll dp[20][200]; 6 ll cnt[200]; 7 int sumdigit(ll x) 8 { 9 int tot=0; 10 while(x) 11 { 12 tot+=x%10

poj3252数位dp

#include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include <qu

数位dp模版(dp)

1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 6 using namespace std; 7 8 int t; 9 long long dp[19][19][2005]; 10 long long l, r; 11 int shu[20]; 12 13 long long dfs(int len,..., bool shangx