【数位DP】——hdu4389——四维表示
X mod f(x)
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2878 Accepted Submission(s): 1130
Problem Description
Here is a function f(x):
int f ( int x ) {
if ( x == 0 ) return 0;
return f ( x / 10 ) + x % 10;
}
Now, you want to know, in a given interval [A, B] (1 <= A <= B <= 109), how many integer x that mod f(x) equal to 0.
Input
The first line has an integer T (1 <= T <= 50), indicate the number of test cases.
Each test case has two integers A, B.
Each test case has two integers A, B.
Output
For each test case, output only one line containing the case number and an integer indicated the number of x.
Sample Input
2
1 10
11 20
Sample Output
Case 1: 10
Case 2: 3
Author
WHU
dp数组存的是一个总和
#include <iostream> #include <string.h> #include<stdio.h> using namespace std; int digit[10]; int dp[10][83][83][83]; // div是除数,不会变的 //sum是剩下的几位的数要凑成的和 , 一直减到0为止 //remain是高位的数除以除数后的余数 // cnt i i 0 true int dfs(int pos , int div , int sum , int remain , bool limit) { if( sum < 0 ) return 0; if( pos < 0 ) return (remain==0&&sum==0)?1:0; if( sum > (pos+1)*9 ) return 0; if(limit==0 && dp[pos][div][sum][remain]!=-1) return dp[pos][div][sum][remain]; int ans=0; int End=limit?digit[pos]:9; for(int i=0;i<=End;i++) { ans+=dfs(pos-1 , div , sum-i , (remain*10+i)%div , limit&&(i==End)); } //dp存的是一般情况 if(limit==0) dp[pos][div][sum][remain]=ans; return ans; } int Solve(int x) { int temp=x; int cnt=-1;//数字的位数 int ans=0; while(temp)//逆置数字 { digit[++cnt]=temp%10; temp/=10; } //枚举除数 for(int i=1 ; i<=cnt*9+digit[cnt] ; i++) ans+=dfs(cnt , i , i , 0 , true); return ans; } int main() { int a,b,t,icase=1; scanf("%d",&t); memset(dp,-1,sizeof(dp)); while(t--) { scanf("%d%d",&a,&b); printf("Case %d: %d\n",icase++,Solve(b)-Solve(a-1)); } return 0; }

浙公网安备 33010602011771号