[数位dp] hdu 3555 Bomb
2014-09-05 12:06
204 查看
题意:求1~n中,带有49的数字有多少个。 4949算一个数字。
思路:设dp[i][j]代表 在i位数首位是j之前,含有49的数有多少个
那么很明显 dp[i][5]的时候 会出现一个显著的增长
拿dp[4][5]举例
因为 4000~4999 中间会有49开头的数这些数每个都是 1000个
其实就是有 10^(i-2)个 但是会有重复。
重复的就是原来去掉49之后 后面的 0~99 之间含有49的个数
这里的就是4949这个算了2次要减掉。
所以状态转移方程就是 dp[i][j]=dp[i][j-1]+dp[i-1][10]
如果j==5要特殊考虑
dp[i][j]=dp[i][j-1]+dp[i-1][10]+10^(i-2)-dp[i-2][10]
初始化完之后就是求了
求的时候一切都正常 就是如果出现49开头的时候
比如49xxx
那么我们要加上 (49xxx%1000+1) 这是以49开头后面的数
但是还要减去 xxx所含有的49的个数 因为这些重复计算了
减去的其实就是一个递归 再算一次 具体见带代码
代码:
思路:设dp[i][j]代表 在i位数首位是j之前,含有49的数有多少个
那么很明显 dp[i][5]的时候 会出现一个显著的增长
拿dp[4][5]举例
因为 4000~4999 中间会有49开头的数这些数每个都是 1000个
其实就是有 10^(i-2)个 但是会有重复。
重复的就是原来去掉49之后 后面的 0~99 之间含有49的个数
这里的就是4949这个算了2次要减掉。
所以状态转移方程就是 dp[i][j]=dp[i][j-1]+dp[i-1][10]
如果j==5要特殊考虑
dp[i][j]=dp[i][j-1]+dp[i-1][10]+10^(i-2)-dp[i-2][10]
初始化完之后就是求了
求的时候一切都正常 就是如果出现49开头的时候
比如49xxx
那么我们要加上 (49xxx%1000+1) 这是以49开头后面的数
但是还要减去 xxx所含有的49的个数 因为这些重复计算了
减去的其实就是一个递归 再算一次 具体见带代码
代码:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" #define eps 1e-8 using namespace std; __int64 dp[22][12]; __int64 ten[22]; __int64 slove(__int64 a) { if(a<49) return 0; if(a<100) return 1; __int64 len,n,t=1,ans=0; len=(__int64)log10(a*1.0)+1; n=len-1; while(n--) t*=10; while(len) { __int64 tep=a/t; if(len==1) tep++; if(len>=2&&a/(t/10)==49) ans+=a%(t/10)+1-slove(a%(t/10)); //注意要减掉 ans+=dp[len][tep]; len--; a%=t; t/=10; } return ans; } int main() { int i,j; memset(ten,0,sizeof(ten)); ten[2]=1; for(i=3;i<=20;i++) ten[i]=ten[i-1]*10; memset(dp,0,sizeof(dp)); for(i=2;i<=20;i++) { for(j=1;j<=10;j++) { dp[i][j]+=dp[i][j-1]+dp[i-1][10]; if(j==5) { dp[i][j]+=ten[i]; dp[i][j]-=dp[i-2][10]; //去重 } } } int t; cin>>t; while(t--) { __int64 n; scanf("%I64d",&n); printf("%I64d\n",slove(n)); } return 0; }
相关文章推荐
- HDU 3555 Bomb (数位DP)
- hdu 3555 - Bomb [数位dp]
- hdu 3555 Bomb(数位DP)
- hdu 3555 Bomb(数位DP,4级)
- HDU 3555 Bomb(数位DP)
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
- HDU 3555 Bomb (数位DP)
- hdu 3555 Bomb(数位dp)
- HDU 3555 Bomb 数位dp
- HDU 3555 Bomb 数位DP
- HDU --3555--Bomb--数位DP
- hdu 3555 Bomb 数位dp
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
- 【数位DP】【HDU 3555】Bomb
- HDU-3555 Bomb 数位DP
- HDU 3555 Bomb 基础数位dp
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
- HDU-3555 Bomb 数位DP
- hdu 3555 Bomb 数位DP
- hdu 3555 Bomb (数位DP)