POJ 2282 Counting Problem

http://poj.org/problem?id=2282

题意:问[a,b]内 数字[0~9]分别出现多少次? a,b<=1e9.

数位DP dp[len][sta]:当前长度为len 数字y的初始状态为sta时,数字y共出现了多少次?

枚举当前位 如果为i!=num ,len-1位y的初始状态为sta

如果i==num ,len-1位y的初始状态为sta+1
当前位<0 则返回y的出现次数

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=3e2+20;
ll a[N],num;
ll dp[N][N];
int dfs(int pos,int sta,bool lead,bool limit)
{
    if(pos==-1)
        return sta;
    if(!lead&&!limit&&dp[pos][sta]!=-1)
        return dp[pos][sta];
    int up=limit?a[pos]:9;
    int res=0;
    for(int i=0;i<=up;i++)
    {
        if(lead&&i==0)
            res+=dfs(pos-1,sta,true,limit&&i==a[pos]);
        else
            res+=dfs(pos-1,sta+(i==num),false,limit&&i==a[pos]);
    }
    if(!lead&&!limit)
        dp[pos][sta]=res;
    return res;
}
int solve(int x)
{
    int pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,0,true,true);
}
int main()
{
    int a,b;
    memset(dp,-1,sizeof(dp));
    while(cin>>a>>b&&(a+b))
    {
        if(a>b)
            swap(a,b);
        num=0;
        cout<<solve(b)-solve(a-1);
        for(num=1;num<=9;num++)
            cout<<‘ ‘<<solve(b)-solve(a-1);
        cout<<endl;
    }
    return 0;
}
时间: 2024-08-26 23:50:38

POJ 2282 Counting Problem的相关文章

POJ 2282-The Counting Problem(组合数学_区间计数)

The Counting Problem Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2282 Appoint description:  System Crawler  (2015-04-15) Description Given two integers a and b, we write the numbers between

POJ 2282 The Counting Problem,组合数学

POJ 2282 The Counting Problem,组合数学 ACM 题目地址:POJ 2282 题意: 给出俩数n,m,求从n~m中0~9分别出现的次数. 分析: 组合数学. 只要能快速算出0~n中各个数的出现次数就能解决问题了. 要把数拆开来看,比如3456=3000+400+50+6. 然后就只要考虑后面都是0的数就行了. 0~3000中,我们要分为两部分来考虑: 在第一位中,0\1\2都出现了1000次. 假设不管第一位,后面那些位数出现0~9的几率是均等的(先不考虑前导0).那

UVALive3261 UVA1640 POJ2282 HDU1663 ZOJ2392 The Counting Problem

Regionals 2004 >> Asia - Shanghai 问题链接:UVALive3261 UVA1640 POJ2282 HDU1663 ZOJ2392 The Counting Problem. 问题简述:输入m和n,计算m到n(包括m和n)之间各个数中包含多少个0-9数字. 问题分析:先分别计算0到m-1和0到n之间数的数字个数,结果=0到n之间数的数字个数-0到m-1之间数的数字个数.计算0到n之间数的数字个数时,先考虑1位数.2位数.......,在小于n的区间逐步统计.

POJ 1681---Painter&#39;s Problem(高斯消元)

POJ   1681---Painter's Problem(高斯消元) Description There is a square wall which is made of n*n small square bricks. Some bricks are white while some bricks are yellow. Bob is a painter and he wants to paint all the bricks yellow. But there is something

HDOJ 1663 The Counting Problem 打表

先打出0~8位数,分别可以被整十/百/千/万...整除时 , 各个数字出现了几次的表 先把每要查询的数字的每一位在表里查询得到一个结果 但是这样是不全面的,考虑这样的情况: 例如2345这样的数 234* 这种情况下 4出现了5次 23**这种情况下3出现了45次 2***中2出现了345次等.....从后往前扫一遍即可 其中0的情况比较特殊,简单的扫一遍会漏掉很多可能 比如 5050时: 500*的情况下,第2个0就没有考虑到,所以还要进行一次补0的操作. 排除首位从前往后扫,遇到每一个不为0

POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 62228   Accepted: 19058 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

The Counting Problem poj2282

/************************************************************************/ /* 递归问题: 给定一个区间,求其中所有0~9数字总计出现次数 思路: 设f(a),f(b)为各自从1开始到a,b中所有0~9数字总计出现次数. 则ans=f(b)-f(a-1);递归的话就是建立f(k)和f(10*k+x)的关系. 对于一个大数,先处理到末尾为0,然后再认为是从0开始10个10个数,数到这个数. 例如,f(2984)就先从298

UVA 1640 The Counting Problem UVA1640 求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数。

/** 题目:UVA 1640 The Counting Problem UVA1640 链接:https://vjudge.net/problem/UVA-1640 题意:求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数. 思路:数位dp: dp[leadzero][i][j][k]表示前面是否选过非0数,即i长度之后可以第一个出现0,而不是前导0,长度为i,前面出现j,k次,j出现的次数. */ #include<iostream> #include<cstri

POJ A Simple Problem with Integers 【线段树,区间更新】

题意:你有N个整数,A1,A2,-,一个.你需要处理两种类型的操作.一种类型的操作是添加了一些给定的数字,每个数字在一个给定的时间间隔.另一种是在给定的时间间隔要求数量的总和. 难点:主要是lazy标记,不好弄懂, 其实lazy标记就是当前改变的值不全部更新,等到用的时候再更新,这样就节省了好多时间. 题目链接:http://poj.org/problem?id=3468 代码: #include<stdio.h> #include<string.h> #define MAXN 1