HDU3555 Bomb[数位DP]
2017-07-01 09:00
429 查看
B - Bomb
HDU - 3555 题意:
给T组数据,每组数组给出一个n,问在[0,n],存在多少个数含有49(49是要连着的,至少含有一个就可以了)。
题解:
只要记录下三个状态,0号状态代表前面没有4,也没有49,1号状态代表前一位是4,那么只要当前位是
4000
9,就可以直接把状态转成2号状态,即当前的数已经存在49后面的数可以任意枚举。
那么状态转移的话,dp[i][j] 第一维表示当前位置,第二维表示三种状态,就上述的三种状态
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<algorithm> #include<queue> #include<stack> #include<set> #include<map> #include<vector> using namespace std; typedef long long ll; const int N=30; ll dp [3]; int num ; ll dfs(int pos,int sta,bool limit)//sta 0前面没有4 1前面有4 2前面有49 { if (pos==-1) return sta==2;//前面是否有49 if (!limit && dp[pos][sta]!=-1) return dp[pos][sta]; ll cnt=0; int mx=limit?num[pos]:9; for (int i=0 ; i<=mx ; ++i) { if ((sta==1 && i==9) || sta==2) cnt+=dfs(pos-1,2,limit && i==num[pos]); else cnt+=dfs(pos-1,i==4,limit && i==num[pos]); } if (!limit) dp[pos][sta]=cnt; return cnt; } ll divi(ll n) { int pos=0; while (n) { num[pos++]=n%10; n/=10; } return dfs(pos-1,0,1); } int main() { int T; scanf("%d",&T); memset(dp,-1,sizeof(dp)); while (T--) { ll n; scanf("%lld",&n); printf("%lld\n",divi(n)); } return 0; }
相关文章推荐
- hdu3555 Bomb(数位DP)
- HDU3555 Bomb 数位DP经典题
- 【HDU3555】Bomb【数位DP】【记忆化搜索】
- hdu3555 Bomb 水数位dp
- HDU3555 Bomb (数位dp)
- hdu3555 Bomb (数位DP)
- 【hdu3555】【数位DP】Bomb
- HDU3555 Bomb 数位DP第一题
- 【1】【数位DP】HDU3555 Bomb
- hdu3555 Bomb ——数位DP入门题
- HDU3555[Bomb]--数位DP
- [暑假集训--数位dp]hdu3555 Bomb
- HDU3555 Bomb(数位DP)
- 【数位DP】HDU3555-Bomb
- 【数位dp】hdu3555 Bomb
- hdu3555 Bomb(数位DP)
- HDU3555 Bomb —— 数位DP
- 【数位DP入门】HDU3555 Bomb
- HDU3555 Bomb(数位dp)
- HDU3555 Bomb[数位DP]