1. 程式人生 > >hdu 4389 X mod f(x) 數位dp

hdu 4389 X mod f(x) 數位dp

滿足 accept sta -a str += tail mar mission

題鏈:http://acm.hdu.edu.cn/showproblem.php?pid=4389

X mod f(x)

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2330 Accepted Submission(s): 919


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.

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


數位dp學習鏈接:http://blog.csdn.net/cyendra/article/details/38087573


題意:相當於問區間內有多少數滿足 X%(∑xi)==0。∑xi 是數字X的數位和。

做法:由於最多9位數,所以能夠枚舉∑xi,最大為81。 然後就是數位dp了。

sum是數位和,nwmod是取模結果,mod 是枚舉的模

當數位和sum==mod並且,nwmod最後==0,成立計數。



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map> 

typedef long long LL;
const int maxn=81;
int dig[maxn];
int f[10][maxn][maxn][maxn];
//nwmod  數取模後 sum 數位和
LL dfs(int pos,int nwmod,int sum,int mod,int limit)
{
	if (pos<0) return sum==mod&&nwmod==0;
	if (!limit&&f[pos][nwmod][sum][mod]!=-1) 
		return f[pos][nwmod][sum][mod];
	LL res=0;
	int last=limit?dig[pos]:9;
	for (int i=0;i<=last;i++)
	{
		res+=dfs(pos-1,(nwmod*10+i)%mod,sum+i,mod,limit&&(i==last));
	}
	if (!limit) f[pos][nwmod][sum][mod]=res;
	return res;
}

LL solve(LL n){
	int len=0; 
	while (n)
	{
		dig[len++]=n%10;
		n/=10;
	}
	LL ans=0;
	for(int i=1;i<=81;i++)//枚舉最後的mod
	{
		ans+=dfs(len-1,0,0,i,1);
	}
	return ans;
}
int main()
{
	int n;
	int t;
	int cas=1;
	scanf("%d",&t);
	int a,b;
	memset(f,-1,sizeof f);
	while(t--)
	{
		scanf("%d%d",&a,&b);
		if(a>b)
			swap(a,b); 
		printf("Case %d: %I64d\n",cas++,solve(b)-solve(a-1));
	}
	return 0; 
}

/*
2
1 10
11 20 

Sample Output
Case 1: 10
Case 2: 3 
*/


hdu 4389 X mod f(x) 數位dp