hdu3555Bomb以及对数位dp的讲解

来源:互联网 发布:ipadcad cad绘图软件 编辑:程序博客网 时间:2024/06/05 20:36

Bomb

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 9295    Accepted Submission(s): 3282


Problem 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
3150500
 

Sample Output
0115
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.
 

Author
fatboy_cw@WHU
 

Source
2010 ACM-ICPC Multi-University Training Contest(12)——Host by WHU



所谓数位dp就是dp+组合数学

首先是预处理出dp:
dp[i][0]:i位数,不包含49的有几个
dp[i][1]:i位数,不包含49但是以9开头的有几个
dp[i][2]:i位数,包含49的有几个
(i位数包含0开头的情况)

组合数学部分:
算1到x有几个数自己含有49时,
为了方便描述,用一个串s储存x,其中0为起始位置,串长为len,
s[i]到s[len-1]组成一个数字y,算出数字恰有len-i位,且不大于y时,且自己含有49的有多少个
枚举所有i,累加即可

注意:
当49已经在之前出现时,要特殊处理
若x本身含有49,记得算上x本身
y可以是0开头,因为若每次都这样,是不会算多的,相当于每次都把下一次的i算了一些情况

#include<map>#include<string>#include<cstring>#include<cstdio>#include<cstdlib>#include<cmath>#include<queue>#include<vector>#include<iostream>#include<algorithm>#include<bitset>#include<climits>#include<list>#include<iomanip>#include<stack>#include<set>using namespace std;typedef long long ll;ll dp[20][3];ll work(string s){int len=s.length();ll ans=0;bool flag=0;for(int i=0;i<len;i++){if(flag)ans+=(dp[len-i-1][0]+dp[len-i-1][2])*(s[i]-'0');else{ans+=dp[len-i-1][2]*(s[i]-'0');if(s[i]>'4')ans+=dp[len-i-1][1];}if(!flag&&i>0&&s[i-1]=='4'&&s[i]=='9')flag=1;}if(flag)ans++;return ans;}int main(){dp[0][0]=1;for(int i=1;i<19;i++){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];}int T;cin>>T;while(T--){string s;cin>>s;cout<<work(s)<<endl;}}


0 0
原创粉丝点击