數位dp dp [len][dig][sum]
長度 首相 和 #1033 : 交錯和
描述
給定一個數 x,設它十進制展從高位到低位上的數位依次是 a0, a1, ..., an - 1,定義交錯和函數:
f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1
例如:
f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4
給定 l, r, k,求在 [l, r] 區間中,所有 f(x) = k 的 x 的和,即:
輸入
輸入數據僅一行包含三個整數,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
#include <bits/stdc++.h> using namespace std; typedef long long ll ; typedef double dl ; #define INF 0x7f const int maxn =1e5+5; const int mod = 1000000007; #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) struct node { ll s,n; // s交錯和 ,n 代表個數 node() { s=0;n=-1; } }; node dp[21][20][400]; ll base[21]; int bits[21]; void init() { node t; f(i,0,20)f(j,0,19)f(k,0,399)dp[i][j][k]=t; base[1]=1; f(i,2,20)base[i]=base[i-1]*10%mod; } node dfs(int len,int dig,bool bz,bool limit,int sum) { node t; t.s=0;t.n=0; //邊界 if(len<=0 || len>=20||dig<0||dig>9||sum<-200||sum>=200 ) return t; //返回結束位置 if(!limit && dp[len][dig+(bz?0:10)][sum+200].n!=-1) return dp[len][dig+(bz?0:10)][sum+200]; if(len==1) { if(dig!=sum) return t; t.n=1,t.s=sum; return t; } //枚舉 int end =limit?bits[len-2]:9; int newsum = dig -sum; node tmp; f(j,0,end) { if(bz) tmp = dfs(len-1,j,j==0,limit&&(j==end),sum); else tmp = dfs(len-1,j,false,limit&&(j==end),newsum); t.n+=tmp.n; //計算滿足條件的長度爲 len 的data[len]所有數的和, tmp 是長度爲 i-1的data[len-1]所有數的和 //每一個: data[len] = dig * base[len] + data[len-1] 且共有n個 //t.s = t.s + tmp.n * (dig * base[len]) + tmp.s 增加 %mod 就得到下面的結果 t.s = ((t.s + tmp.s) % mod + ((tmp.n * dig) % mod * base[len]) % mod) % mod; } if(!limit) dp[len][dig+(bz?0:10)][sum+200]=t; return t; } ll slove(ll n ,ll s ) { if(n<=0)return 0; int l =0; f(i,0,20) bits[i]=0; while(n) { bits[l++]=n%10; n/=10; } return dfs(l+1,0,true,true,s).s; } int main() { freopen("in","r",stdin); init(); ll l,r,s; cin>>l>>r>>s; cout<<(slove(r,s)-slove(l-1,s)+mod)%mod<<endl; cout<<"hello"<<endl; return 0; }