数位dp HDU 3555 Bomb

Description

The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would add one point. 
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them? 

Input

The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description. 

The input terminates by end of file marker. 

Output

For each test case, output an integer indicating the final points of the power.

Sample Input

3
1
50
500

Sample Output

0
1
15

Hint

From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499", so the answer is 15.

首先应该初始化,分为dp[i][0]dp[i][1]dp[i][2],分别表示不含有49的,不含49但最高位是9的,含有49的,递推关系是dp[i][0]=dp[i-1][0]*10-dp[i-1][1];dp[i][1]=dp[i-1][0];dp[i][2]=dp[i-1][2]*10+dp[i-1][1];之后读取数字,后从高位往下看,先加上有49的那部分,如果前面已经有49了那就再把不含49的那部分也加进去,如果前面不含49,但是现在查询到的这个数大于4的话那就只加之后的以9开头且不含49的数的个数,最后再判断一下加了这个数是不是就可以包含49这个数了,要注意的是数据比较大,所以要用__int64型。

#include <stdio.h>
#include <cstring>

__int64 dp[20][3],a[20],l;

void init()
{
	int i;
	memset(dp,0,sizeof(dp));
	dp[0][0]=1;					//
	for(i=1;i<20;i++)
	{
		dp[i][0]=(__int64)dp[i-1][0]*10-dp[i-1][1];
		dp[i][1]=(__int64)dp[i-1][0];
		dp[i][2]=(__int64)dp[i-1][2]*10+dp[i-1][1];
	}
}

int main()
{
	int i;
	int t;
	__int64 n;
	init();
	scanf("%d",&t);
	while(t--)
	{
		memset(a,0,sizeof(a));
		__int64 ans=0;
		l=1;
		int flag=0;
		scanf("%I64d",&n);
		n++;					//应当注意到不加这一项的话,例如n=49时就无法取到正确的解,感觉原因像
								//是因为做if(!flag&&a[i]>4)判断时把49这种可能性忽略了,加上去之后49自
								//然就行了,而因为这个进位的,由于进位后dp会自动加上dp[i-1][1],所以仍然成立
		while(n)
		{
			a[l++]=n%10;
			n=n/10;
		}
		for(i=l-1;i>=1;i--)
		{
			ans+=(__int64)dp[i-1][2]*a[i];
			if(flag)
				ans+=(__int64)dp[i-1][0]*a[i];
			if(!flag&&a[i]>4)
				ans+=(__int64)dp[i-1][1];
			if(a[i]==9&&a[i+1]==4)
				flag=1;
		}
		printf("%I64d\n",ans);
	}
	return 0;
}


发布了62 篇原创文章 · 获赞 46 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章