hihocoder1033(数位dp)

来源:互联网 发布:石金鑫知乎 编辑:程序博客网 时间:2024/05/29 07:35

题目:

给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数:

f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1

例如:

f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4

给定 

1405402477702.png

输入

输入数据仅一行包含三个整数,l, r, k(0 ≤ l ≤ r ≤ 1018, |k| ≤ 100)。

输出

输出一行一个整数表示结果,考虑到答案可能很大,输出结果模 109 + 7

提示

对于样例 ,满足条件的数有 110 和 121,所以结果是 231 = 110 + 121。

更多样例:

Input4344 3214567 3
Output611668829
Input404491953 1587197241 1
Output323937411
Input60296763086567224 193422344885593844 10
Output608746132Input100 121 -1
Output120



样例输入
100 121 0
样例输出
231


解法:数位dp,dp[pos][aim][len%2],记录的是,长度为len,从pos以下位置,在没有任何约束的情况下,结果为aim的交错和。增加一维[len%2]是因为len的奇偶性会影响pos后每位的正负性。dp中,sum为所有结果为aim的数的交错和,n为所有结果为aim的数的个数。


代码:

/******************************************************* @author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>//freopen ("in.txt" , "r" , stdin);using namespace std;#define eps 1e-8#define zero(_) (abs(_)<=eps)const double pi=acos(-1.0);typedef long long LL;const int Max=22;const LL INF=1e9+7;int bit[Max];int len;int p=0;struct node{    LL sum;    LL n;};node dp[22][400][2];LL help[22];node dfs(int pos,int aim,bool limit,bool stt){    node re;    re.n=0;    re.sum=0;    if(pos==0)    {        if(aim==100)            re.n=1;        return re;    }    if(!limit&&!stt&&dp[pos][aim][len%2].n!=-1)    {        return dp[pos][aim][len%2];    }    int end=limit?bit[pos]:9;    int st= stt?1:0;    for(int i=st; i<=end; i++)    {        int add=((len-pos)%2==0?-1:+1);        node next=dfs(pos-1,aim+add*i,limit&&i==end,0);        re.sum=(re.sum+next.sum+next.n*help[pos]*i%INF)%INF;        re.n=(re.n+next.n)%INF;    }    if(!limit&&!stt)        return dp[pos][aim][len%2]=re;    return re;}LL getans(LL n,int aim){    if(n<=0)        return 0;    p=0;    while(n)    {        bit[++p]=n%10;        n/=10;    }    LL ans=0;    for(len=1; len<=p; len++)    {        ans=(ans+dfs(len,aim+100,len==p,1).sum)%INF;    }    return ans;}int main(){    LL l,r;    int aim;    memset(dp,-1,sizeof dp);    help[1]=1;    for(int i=2;i<22;i++)    help[i]=(help[i-1]*10)%INF;    while(cin>>l>>r>>aim)    {        cout<<(getans(r,aim)-getans(l-1,aim)+INF)%INF<<endl;    }    return 0;}


0 0
原创粉丝点击