hdu3652(数位dp)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3652

题意:求1~n含有13且能被13整除的数的个数。

分析:数位dp,dp数组加一维来维护到pos位模13的余数,则dp[pos][mod][2]表示非限制条件下到pos位模13余mod且已含有13的总个数,dp[pos][mod][1]表示没含有13但前一位是1且模13余mod的总个数,dp[pos][mod][0]表示没含有13前一位不为1模13余mod的总个数。。。

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 10007
#define inf 0x3f3f3f3f
#define N 100010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int dp[12][15][3];
int dig[12];
int dfs(int pos,int pre,int md,int flag,int limit)
{
    if(!pos)return flag&&md==0;
    if(!limit&&flag&&~dp[pos][md][2])return dp[pos][md][2];
    if(!limit&&!flag&&pre==1&&~dp[pos][md][1])return dp[pos][md][1];
    if(!limit&&!flag&&pre!=1&&~dp[pos][md][0])return dp[pos][md][0];
    int len=limit?dig[pos]:9;
    int ans=0;
    for(int i=0;i<=len;i++)
    {
        ans+=dfs(pos-1,i,(md*10+i)%13,flag||(pre==1&&i==3),limit&&i==len);
    }
    if(!limit)
    {
        if(flag)dp[pos][md][2]=ans;
        else if(pre==1)dp[pos][md][1]=ans;
        else dp[pos][md][0]=ans;
    }
    return ans;
}
int solve(int x)
{
    int len=0;
    while(x)
    {
        dig[++len]=x%10;
        x/=10;
    }
    return dfs(len,0,0,0,1);;
}
int main()
{
    int n;
    while(scanf("%d",&n)>0)
    {
        memset(dp,-1,sizeof(dp));
        printf("%d\n",solve(n));
    }
}

时间: 2024-12-17 00:07:14

hdu3652(数位dp)的相关文章

hdu3652 数位dp(含13且被能被13整除的数)

http://acm.hdu.edu.cn/showproblem.php?pid=3652 B-number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2815    Accepted Submission(s): 1552 Problem Description A wqb-number, or B-number for sh

hdu3652 数位dp

dp[i][j][k]  i-i位数,j-开头是j,k-除13的余数 要注意数位dp的时候一定不能直接判断对的来做,必须是判断不对的,然后用全部减 这一题先算出所有%13==0的个数,然后算出所以%13并且不含13的个数,然后相减就是答案了 #include<bits/stdc++.h> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 2520 #define ls l,m,rt<

hdu3652 数位dp记忆化搜索

从未见过的船新版本数位dp,,省去了预处理过程,直接进行计算 #include<bits/stdc++.h> using namespace std; #define ll long long int dp[20][20][5],n,len,bit[20]; //dp[i][j][k]:到i位数,前面模13=j,前面是1|不是1|有13的状态已经确定,后面的数的个数 //mod:前面%13的余数,flag=0|1|2:pos+1位不是1|是1|有13出现过了,lim:数的限制 int dfs(

数位DP HDU3652

B-number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5000    Accepted Submission(s): 2866 Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal for

[暑假集训--数位dp]hdu3652 B-number

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 is to calculate how many wqb

【hdu3652】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

hdu3652 B-number(数位dp+dfs)

B-number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3376 Accepted Submission(s): 1891 Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal form con

hdu3652---B-number(数位dp)

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 is to ca

数位dp专题 (HDU 4352 3652 3709 4507 CodeForces 55D POJ 3252)

数位dp核心在于状态描述,因为阶段很简单. 一般都是求有多少个数,当然也有求平方的变态题. 因为比这个数小的范围定然是从左至右开始小的,那么什么样的前缀对后面子数有相同的结果? HDU 3652 题意:求能被13整除且含有13这样数的个数. 赤裸裸的两个条件,加上个pre标明下前缀,其实直接开状态也是一样的.整除这个条件可以用余数来表示.余数转移:(mod*10+i)%13 /* *********************************************** Author :bi