hdu 2089

开始学一下数位dp 有一个地方不理解 先标记一下

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <cmath>
#include <deque>
#include <stack>
#include <cctype>
#include <iomanip>
using namespace std;

typedef long long ll;
typedef long double ld;

const int N = 10;
const int INF = 0xfffffff;
const double EPS = 1e-8;
const ll MOD = 1e9 + 7;
const ld PI = acos (-1.0);

#define INFL 0x7fffffffffffffffLL
#define met(a, b) memset(a, b, sizeof(a))
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a)

int dp[N][2], bit[N];
int dfs (int len, bool is6, bool ismax);
int calc (int n);

int main ()
{
    int n, m;
    met (dp, -1);
    while (cin >> m >> n, m || n)
    {
        cout << calc (n) - calc (m-1) << endl;
    }
    return 0;
}

int dfs (int len, bool is6, bool ismax) // 长度 状态 是否达到上限
{
    if (len == 0) return 1; //如果长度为0 证明此串合法
    if (!ismax && dp[len][is6] >= 0) return dp[len][is6];  //如果不是最高位 且已经搜索过 直接返回
    // 为什么要求不是最高位 才能直接返回呢
    //比如 5431   对于4xxx 3xxx 当len为3的时候都可以直接返回 因为之前已经计算过
    //而5xxx 最多只能取到5431 必须要重新计算
    int cnt = 0, maxnum = (ismax ? bit[len] : 9); //如果是最高位 只能取到bit[len]
     for (int i=0; i<=maxnum; i++) //枚举
    {
        if (i == 4 || (is6 && i == 2)) continue; //不能有4 且不能有62
        cnt += dfs (len - 1, i == 6, ismax && i == maxnum); // 递归搜索
    }
    return ismax ? cnt : dp[len][is6] =  cnt;// 根据ismax来决定是否记录dp
    //(比如dp[3][1]记录的是6xx的所有数,即从600到699中的符合条件的数的个数)
}

int calc (int n)
{
    int len = 0;
    while (n)
    {
        bit[++len] = n % 10;
        n /= 10;
    }
    return dfs (len, false, true);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值