1248.B.陆历川玩数位

Time Limit: 500 MS    Memory Limit: 131072 KB
Total Submission(s): 11    Accepted Submission(s): 7

Description

A number X have n digits(A1A2A3......An)

F(x) = A1*2n-1 + A2*2n-1 .....+An-1*21 + An *20

Now, give you two number A, B

You need to calculate how many number's F(x) is no more than F(A) between 0 to B

Input

T(0 < T<= 10000) T is TestCase

A, B (0 <= A, B <= 1000000000)

Output

Answer

Sample Input

11 1

Sample Output

Case #1: 2
           这道题是一道模板题~~看清题意做就好。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int dp[20][10002];//最大的时候也不是太大~开个10000+的数组就好了
int maxn[20];
int num;
int f(int x)//求他的f(x)是多少
{
	if (x == 0)
	{
		return 0;
	}
	int ans = f(x / 10);
	return ans * 2 + (x % 10);
}
int poww(int x)求这个2的x幂是多少
{
	int ans = 1;
	while (x--)
	{
		ans = ans * 2;
	}
	return ans;
}
int dfs(int pos, int sum, bool limit)进行dfs遍历
{
	if (pos == -1)如果f(x)>num;就不加入结果
	{
		return sum<=num;
	}
	if (sum > num)同上
	{
		return 0;
	}
	if (!limit&&dp[pos][num-sum] != -1)一定要注意边界的limit~所有的dp记忆化都要加上!limit
	{
		return dp[pos][num-sum];
	}
	int ans = 0;
	int up = limit ? maxn[pos] : 9;//查询上界
	for (int s = 0; s <= up; s++)
	{
		ans += dfs(pos - 1, (sum + poww(pos)*s), limit && (maxn[pos] == s));
	}
	if (!limit)
	{
		dp[pos][num-sum] = ans;记忆化
	}
	return ans;
}
int solve(int x)把边界储存下来;
{
	int pos = 0;
	while (x)
	{
		maxn[pos++] = x % 10;
		x = x / 10;
	}
	return dfs(pos - 1, 0, 1);
}
int main()
{
	memset(dp, -1, sizeof(dp));
	int te;
	scanf("%d", &te);
	int k = 1;
	while (te--)
	{
		int a, b;
		scanf("%d %d", &a, &b);
		num = f(a);
		printf("Case #%d: %d\n",k++, solve(b));
	}
	return 0;
}