數位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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章