hdu3555

hdu3555 Bomb
传送门

题意

计算\([1,n](1\leq n\leq 2^{63}-1)\)中有多少数含有49

题解

数位\(dp\)
预处理边界的数位,得到边界数组,之后从高位到低位进行数位\(dp\)
\(dp[i][0]\)表示直到第\(i\)位,不含\(49\)的个数
\(dp[i][1]\)表示直到第\(i\)位,没有\(49\)但是前一位是\(4\)的个数
\(dp[i][2]\)表示直到第\(i\)位,含有\(49\)的个数

#include<bits/stdc++.h>
#define LL long long
#define PII pair<int,int>
using namespace std;

int T,bit[70];
LL n,dp[70][5];

int divide(LL x){
	int cnt=0;
	while(x){
		bit[cnt++]=x%10;
		x/=10;
	}
	return cnt;
}

LL dfs(int pos,int sta,bool limit){
	if(pos==-1) return sta==2;
	if(!limit && dp[pos][sta]!=-1) return dp[pos][sta];
	int up=limit?bit[pos]:9;
	LL ans=0;
	for(int i=0;i<=up;i++){
		if(sta==2 || (sta==1 && i==9)){
			ans+=dfs(pos-1,2,limit && i==up);
		}
		else if(i==4){
			ans+=dfs(pos-1,1,limit && i==up);
		}
		else{
			ans+=dfs(pos-1,0,limit && i==up);
		}
	}
	if(!limit) dp[pos][sta]=ans;
	return ans;
}

int main(){
	memset(dp,-1,sizeof(dp));
	scanf("%d",&T);
	while(T--){
		scanf("%lld",&n);
		int cnt=divide(n);
		LL ans=dfs(cnt-1,0,1);
		printf("%lld\n",ans);
	}
}
posted @ 2020-12-01 19:03  fxq1304  阅读(35)  评论(0编辑  收藏  举报