hdu2089 不要62 (数位DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089


#include <stdio.h>  
#include <string.h>  

int dp[10][3],digits[10];

void Init()
{
	int i;
	dp[0][0]=1;
	dp[0][1]=dp[0][2]=0;
	for(i=1;i<10;++i)
	{
		dp[i][0]=9*dp[i-1][0]-dp[i-1][1];//在最高位加上除了4之外的9个数字,但是可能在2之前加了6
		dp[i][1]=dp[i-1][0];//最高位2
		dp[i][2]=10*dp[i-1][2]+dp[i-1][0]+dp[i-1][1];
		//在已经有不吉利数字最高位加任意数字,或者在无吉利数字前加4,或者在2前面加4
	}
}

int slove(int n)
{
	int i,len,temp,flag,ans;
	temp=n;
	len=0;
	while(temp)
	{
		digits[++len]=temp%10;
		temp/=10;
	}
	digits[len+1]=0;
	ans=0;
	flag=0;
	for(i=len;i>=1;--i)
	{
		ans+=dp[i-1][2]*digits[i];
		if(flag)//高位已经出现4或者62
			ans+=dp[i-1][0]*digits[i];
		if(!flag&&digits[i]>4)
			ans+=dp[i-1][0];
		if(!flag&&digits[i+1]==6&&digits[i]>2)//高位是6,后面一位可能出现2
			ans+=dp[i][1];
		if(!flag&&digits[i]>6)//高位可能出现6,要把后面最高位为2计入
			ans+=dp[i-1][1];
		if(digits[i]==4||(digits[i+1]==6&&digits[i]==2))
			flag=1;
	}
	return n-ans;
}

int main()
{
	int n,m,num1,num2;
	Init();
	while(scanf("%d %d",&n,&m)&&((n+m)!=0))
	{
		num1=slove(m+1);
		num2=slove(n);
		printf("%d\n",num1-num2);
	}
	return 0;
}


你可能感兴趣的:(hdu2089 不要62 (数位DP))