hdu2089 【数位dp】

版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/82792136

题目大意就是问在一个给定的区间里的数不包含62,和4的数有多少个?

思路:数位dp一般是用来解决在排列中删去一些不符合要求的数后的个数,所以这道题很明显是数位dp

代码:

#include<cstdio>
#include<iostream>
using namespace std;

int dp[20][20];//dp[I][j]表示长度位I,最高位位j时的满足条件的数的个数,也就是没有62或者4的个数
int a[20];

void get()
{
		dp[0][0] = 1;
		for (int i = 1; i <= 10; i++)
		{
				for (int j = 0; j<10; j++)
				{
						if (j == 4) dp[i][j] = 0;
						else if (j == 6)
						{
								for (int k = 0; k<10; k++)
								{
										dp[i][j] += dp[i - 1][k];
								}
								dp[i][j] -= dp[i - 1][2];
						}
						else
						{
								for (int k = 0; k<10; k++)
								{
										dp[i][j] += dp[i - 1][k];
								}
						}
				}
		}
}

long long  solve(int n)
{
		a[0] = 0;
		long long ans = 0;
		while (n)
		{
				a[++a[0]] = n % 10;
				n /= 10;
		}
		a[a[0] + 1] = 0;
		for (int i = a[0]; i >= 1; i--)
		{
				for (int j = 0; j<a[i]; j++)
				{
						if (j != 4 && !(a[i + 1] == 6 && j == 2))
								ans += dp[i][j];
				}
				if (a[i] == 4) break;
				if (a[i + 1] == 6 && a[i] == 2) break;
		}
		return ans;
}

int main()
{
		int n, m;
		get();
		while (scanf("%d %d", &n, &m) && (n || m))
		{
				long long ans1 = solve(m + 1);
				long long ans2 = solve(n);
				cout << ans1 - ans2 << endl;
		}
		return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/82792136