以前一直不知道该咋搞这个比较好。

感觉推起来那个数字好麻烦。后来有一种比较好的写法就是直接的DFS写法。相应的ismax表示当前位是否有限制。

数位DP也是有一种类似模版的东西,不过需要好好理解。与其他模版不同。

主要还是状态的定义

模版就不整理了。直接上题。

另外这里有一道题是数位DP+自动机的放到自动机里做

HDU 2089 不要62

基本的数位DP可以用来理解DFS写法

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 15;
int dp[MAXN][2];
int digit[MAXN],length;

int calcu(int len,bool issix,bool ismax)
{
    if (len == 0) return 1;
    if (!ismax && dp[len][issix] != -1) return dp[len][issix];
    int limit = ismax ? digit[len] : 9;
    int tot = 0;
    for (int i = 0 ; i <= limit ; i++)
    {
        if ((issix && i == 2) || i == 4 ) continue;
        tot += calcu(len - 1,i == 6 ,ismax && i == limit);
    }
    if (ismax) return tot;
    else return dp[len][issix] = tot;
}

int slove(int x)
{
    int len = 0;
    int num = x;
    while (num)
    {
        digit[++len] = num % 10;
        num /= 10;
    }
    return calcu(len,false,true);
}

int main()
{
    memset(dp,-1,sizeof(dp));
    int l,r;
    while (scanf("%d%d",&l,&r) != EOF)
    {
        if (l == 0 && r == 0) break;
        if (l > r) swap(l,r);
        printf("%d\n",slove(r) - slove(l - 1));
    }
    return 0;
}
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-24
  • 2021-10-29
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-17
相关资源
相似解决方案