转自http://blog.csdn.net/zhaoxinfan/article/details/8707605
下面先给出数位DP的背景:
为了降低时间复杂度,可以借鉴传统DP中状态转换,打表这些思路,得到了数位DP:
F(A,B) = F(B,0)-F(A-1,0)
暴力+存储 = 记忆化搜索
针对上面几种类型的问题,数位DP解决方案如下:(具体可以看http://www.cppblog.com/Yuan/archive/2011/07/15/139299.html)
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdlib> 4 #include<cstring> 5 using namespace std; 6 typedef long long ll; 7 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 10 const int L = 20, P = 1e9+7; 11 12 struct RES 13 { 14 ll all, sum, cnt; 15 RES() {} 16 RES(int i,int j,int k):all(i),sum(j),cnt(k) {} 17 } dp[L]; 18 19 ll chkmod(ll x,ll p) 20 { 21 return (x%p+p)%p; 22 } 23 24 int d[L], n; 25 26 RES dfs(int pos, int UP) 27 { 28 if(pos<0) 29 { 30 return RES(0,0,1); 31 } 32 if(!UP && ~dp[pos].all) 33 { 34 return dp[pos]; 35 } 36 RES ret(0,0,0); 37 int up=UP?d[pos]:9; 38 ret.all += dfs(pos-1, UP&&up==0).all; 39 ret.all %= P; 40 for(int i=1;i<=up;i++) 41 { 42 int nUP = UP&&i==up; 43 for(int j=pos-1;j>=-1;j--) 44 { 45 ll tmp = dfs(j, nUP).sum + dfs(j, nUP).cnt * (pos - 1 - j); 46 tmp %= P; 47 ret.all += tmp; 48 ret.all %= P; 49 ret.sum += tmp; 50 ret.sum %= P; 51 ret.cnt += dfs(j, nUP).cnt; 52 ret.cnt %= P; 53 54 nUP = nUP && d[j]==0; // !!! 55 } 56 } 57 58 if(!UP) 59 { 60 dp[pos] = ret; 61 } 62 return ret; 63 } 64 65 ll cal(ll x) 66 { 67 n=0; 68 while(x) 69 { 70 d[n++]=x%10; 71 x/=10; 72 } 73 return dfs(n-1,1).all; 74 } 75 76 int main() 77 { 78 mem(dp,-1); 79 ll n; 80 while(cin>>n) 81 { 82 cout<<cal(n)<<endl; 83 } 84 return 0; 85 }