http://www.cnblogs.com/jffifa/archive/2012/08/17/2644847.html
写得够好了
个人习惯从1计数。。无伤大雅。。
dp数组最开始memset成-1一次就够了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int dfs(int i,int s,int e) { if(!i)return s==target_s ; if(!e && dp[i][s]!=-1)return dp[i][s] ; int u=e?digit[i]:9 ; int res=0 ; for(int d=0 ;d<=u ;d++) res+=dfs(i-1,new_s,e && d==u) ; return e?res:dp[i][s]=res ; } int callen(int n) { int cnt=0 ; while(n) { cnt++ ; n/=10 ; } return cnt ; } void caldigit(int n,int len) { memset(digit,0,sizeof(digit)) ; for(int i=1 ;i<=len ;i++) { digit[i]=n%10 ; n/=10 ; } } int solve(int n) { int len=callen(n) ; caldigit(n,len) ; return dfs(len,0,1) ; }