HDU 3555——Bomb

来源:互联网 发布:法治知识网络大赛入口 编辑:程序博客网 时间:2024/04/29 16:45

这也是一道数位dp的题。

题意:

让你在1~N中间找出含有“49”的数有几个,并输出。

思路:

这一开始我想着和上一题一样,正着枚举,但是发现这样子不太方便,后来借鉴了别人的思路发现我们可以反着做,先找出不含有49的数有几个,然后用N减掉就好了。这里还包含了0,所以记得要加上1。

*然后dp[dep][pre]记得要开LL,要不然会WA。


#include<cstdio>#include<cstring>#include<map>#include<set>#include<cmath>#include<algorithm>#include<vector>#include<queue>#include<iostream>#include<time.h>using namespace std;typedef __int64 ll;typedef unsigned __int64 ULL;#define pi acos(-1.0)#define Ex exp(1.0)#define maxn 66int dig[maxn],vis[maxn][maxn];ll dp[maxn][maxn];//要用__int64存!ll go(int dep,int pre,int less){if(dep<0) return 1;else if(vis[dep][pre]&&less) return dp[dep][pre];else{if(less){ll& tmp=dp[dep][pre];vis[dep][pre]=1;for(int i=0;i<10;i++){if(pre!=4||(pre==4&&i!=9)){tmp+=go(dep-1,i,1);}}return tmp;}else{ll tmp=0;for(int i=0;i<=dig[dep];i++){if(pre!=4||(pre==4&&i!=9)){tmp+=go(dep-1,i,i!=dig[dep]);}}return tmp;}}}ll solve(ll x){int len=0;while(x){dig[len++]=x%10;x=x/10;}return go(len-1,0,0);//!!!反着做的思路}int main(){ll n;int T;while(~scanf("%d",&T)){while(T--){scanf("%I64d",&n);printf("%I64d\n",n-solve(n)+1);//因为它把0也给算进去了,所以最后要加上1}}#ifndef ONLINE_JUDGEsystem("pause");#endifreturn 0;}/*3150500 */


0 0
原创粉丝点击