【數位dp 求滿足的值和】hihocoder 1033 交錯和

CN_swords發表於2017-08-23

Link:http://hihocoder.com/problemset/problem/1033

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9+7;

struct Node{
    LL n,s;
}dp[20][10][2][405];

LL power[20];
int bits[20];
void init(){
    power[0] = 1;
    for(int i = 1; i < 20; i++)
        power[i] = (power[i-1]*10)%mod;

    for(int pos = 0; pos < 20; pos++)
        for(int dig = 0; dig < 10; dig++)
            for(int op = 0; op < 2; op++)
                for(int sum = 0; sum <= 400; sum++)
                    dp[pos][dig][op][sum].n=-1, dp[pos][dig][op][sum].s=0;
}

Node dfs(int pos,int dig,bool op,int sum,int limit){
    Node res;
    res.n = 0, res.s = 0;
    if(pos < 0 || sum < -200 || sum > 200)
        return res;
    if(pos == 0){
        if(dig!=sum)
            return res;
        res.n = 1, res.s = sum;
        return res;
    }
    if(!limit && dp[pos][dig][op][sum+200].n!=-1)
        return dp[pos][dig][op][sum+200];
    int up = limit ? bits[pos] : 9;
    Node temp;
    for(int i = 0; i <= up; i++)
    {
        if(op) temp = dfs(pos-1, i, 1, dig-sum, limit&&(i==up));
        else temp = dfs(pos-1, i, i!=0, sum, limit&&(i==up));
        res.n += temp.n;
        res.s = ( (res.s+temp.s)%mod + (temp.n*dig%mod*power[pos]%mod) )%mod;
    }
    if(!limit) dp[pos][dig][op][sum+200] = res;
    return res;
}

LL solve(LL n,int k)
{
    if(n==0) return 0;
    int pos = 0;
    while(n){
        bits[++pos] = n%10;
        n/=10;
    }
    return dfs(pos,0,0,k,1).s;
}
int main()
{
    init();
    LL l,r;
    int k;
    cin >> l >> r >> k;
    cout << (solve(r,k)-solve(l-1,k)+mod)%mod << endl;
//    scanf("%I64d%I64d%d",&l,&r,&k);
//    printf("%I64d\n",(solve(r,k)-solve(l-1,k)+mod)%mod);
    return 0;
}


相關文章