HDU 3555 Bomb

来源:互联网 发布:php xml 特殊字符转义 编辑:程序博客网 时间:2024/06/06 17:25

题意:

要求1~n的所以数中含49的数得个数。

思路:

数位DP。

用dp[i][0]表示长度为i且不含49的个数。

用dp[i][1]表示长度为i且不含49但最高位为9的个数(注意:上面那个是包含这个的)。

用dp[i][2]表示长度为i且含49的个数。

转移方程为:

dp[i][0]=10*dp[i-1][0]-dp[i-1][1];

dp[i][1]=dp[i-1][0];

dp[i][2]=10*dp[i-1][2]+dp[i-1][1];

利用转移方程先预处理出1~20位(因为2^63次方最多为19位)的所有符合意思的个数。

然后接下来将n拆分成一位一位的数,从高位开始枚举,详见代码。

#include<cstdio>#include<cstring>typedef __int64 LL;LL dp[25][5];void init(){memset(dp,0,sizeof(dp));dp[0][0]=1;for(int i=1;i<=20;i++){dp[i][0]=10*dp[i-1][0]-dp[i-1][1];dp[i][1]=dp[i-1][0];dp[i][2]=10*dp[i-1][2]+dp[i-1][1];}}LL Sum(LL n){int dight[25],cnt=1;while(n){dight[cnt++]=n%10;n/=10;}dight[cnt]=-1;LL ans=0;bool flag=false;for(int i=cnt-1;i>=1;i--){ans+=dight[i]*dp[i-1][2];if(flag) ans+=dight[i]*dp[i-1][0];//如果n已经含有49那么后面的数都可以加上不含49的else if(dight[i]>4) ans+=dp[i-1][1];//如果n大于4那么dight[i]肯定能枚举到4,所以这里加上最高位为9的个数if(dight[i+1]==4&&dight[i]==9) flag=true;}return ans;}int main(){init();LL n;int T;scanf("%d",&T);while(T--){scanf("%I64d",&n);printf("%I64d\n",Sum(n+1));}return 0;}


0 0
原创粉丝点击