hdu3555Bomb 数位dp

#include<cstdio>

#include<cstring>

#include<iostream>

using namespace std ;

const int maxn = 20 ;

int bit[maxn] ;

__int64 dp[maxn][maxn][2] ;//dp[i][j][1]第i位数为j时内有49的数量,0位不含

void init()

{

memset(dp , 0 ,sizeof(dp)) ;

for(int i = 0;i <= 9;i++)

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

for(int i = 2;i < maxn ;i++)

for(int j = 0;j <= 9;j ++)

for(int k = 0;k <= 9 ;k++)

{

if(j == 4 && k == 9)

dp[i][j][1] += (dp[i-1][k][1] + dp[i-1][k][0]) ;

else

{

dp[i][j][1] += dp[i-1][k][1] ;

dp[i][j][0] += dp[i-1][k][0] ;

}

}

}

__int64 solve(int len)

{

__int64 ans = 0 ;

int flag = 0;

for(int i = len;i > 0 ;i--)

{

for(int j = 0;j <  (i == 1 ? (bit[i]+1) : bit[i]) ;j++)

ans+=dp[i][j][1] ;

if(flag == 2)

for(int j = 0;j < (i == 1 ? (bit[i] + 1): bit[i] );j++)

ans+=dp[i][j][0];

if(flag == 1 && i == 1 && bit[1] ==9 )

ans++ ;

if(flag == 1 && bit[i] == 9)

flag = 2;

else if(bit[i] == 4 && flag == 0)

flag = 1;

else if(flag == 1 && bit[i] !=4)

flag = 0;

}

return ans ;

}

int main()

{

// freopen("input.txt","r",stdin) ;

int T ;

scanf("%d" ,&T) ;

__int64 n;

while(T--)

{

scanf("%I64d" ,&n) ;

__int64 t = n;

int len = 0;

while(t)

{

bit[++len] = t%10 ;

t/=10 ;

}

init() ;

printf("%I64d\n" ,solve(len)) ;

}

return 0;

}

时间: 2024-08-14 19:32:11

hdu3555Bomb 数位dp的相关文章

Hdu3555Bomb数位dp

含有49的 ..就是不要49 ..也可以直接搞 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <

hdu3555---Bomb(数位dp,水)

Problem Description The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49&quo

hdu3555Bomb以及对数位dp的讲解

Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 9295    Accepted Submission(s): 3282 Problem Description The counter-terrorists found a time bomb in the dust. But this time the terrorists

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是

51nod1043(数位dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 题意:中文题诶- 思路:数位dp 我们用dp[i][j]来存储长度为2*i且一半和为j的所有情况(包括前导0的情况),为了方便我们现在只讨论其一半的和的情况,因为如果包括前导0的话其两边的情况是一样的: 我们假设再长度为i-1的数字最前面加1位数字k,0<=k<=9(这位数字加在哪里并不影响答案,因为我们在计算i-1长度的时候已经计算了所有组合情况,

数位dp

1.[hdu3709]Balanced Number 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 #include<algorithm> 7 #include<ctime> 8 #include<cmath> 9 #include<queue>

【HDU 3652】 B-number (数位DP)

B-number Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task

hdu 5898 odd-even number 数位DP

odd-even number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 716    Accepted Submission(s): 385 Problem Description For a number,if the length of continuous odd digits is even and the length