标签:
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2945 Accepted Submission(s): 1348
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; #define LL long long #define maxn 30 LL dp[maxn][maxn][2500]; // dp[i][k][j]代表长度为i,中心点为k,最高位到与最高位距离为i的位置经过的数字的权值之和j的数字有多少种 LL digit[maxn]; __int64 dfs(int len,int cen,int pre,bool fp) //dfs版本的纯属暴力枚举每一个数字,而递推版本的是考虑了前缀的影响 { if(len==0) return pre==0; if(pre<0) return 0; if(!fp && dp[len][cen][pre] != -1) // { return dp[len][cen][pre]; } LL ret =0; int fpmax = fp ? digit[len] : 9; for(int i=0;i<=fpmax;i++) //分别算出以i开头的数的方案数, { LL temp=dfs(len-1,cen,pre+i*(len-cen),fp && i == fpmax); ret+=temp; } if(!fp) dp[len][cen][pre]= ret; return ret; } LL f(LL n) { if(n==-1) return 0; int len=0; while(n) { digit[++len] = n % 10; n /= 10; } LL ans=0; for(int cen=1;cen<=len;cen++) { ans+=dfs(len,cen,0,true); } return ans-len+1; } void init() { memset(dp,-1,sizeof(dp)); } int main() { // freopen("test.txt","r",stdin); int t; scanf("%d",&t); while(t--) { init(); LL n,m; scanf("%I64d%I64d",&n,&m); LL ans1=f(m); // init(); LL ans2=f(n-1); printf("%I64d\n",ans1-ans2); } return 0; }
标签:
原文地址:http://www.cnblogs.com/xianbin7/p/4742463.html