hihocoder1033(数位dp)

题目:

给定一个数 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。

更多样例:

Input
4344 3214567 3
Output
611668829
Input
404491953 1587197241 1
Output
323937411
Input
60296763086567224 193422344885593844 10
Output
608746132
Input
100 121 -1
Output
120



样例输入
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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//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<


你可能感兴趣的:(数位dp)