immiq的博客
immiq的博客

acm模板-数位dp

数位DP

#define D 10
#define L 21

int a[L];
LL dp[L][D][]...;

LL dfs(int len, int pos, int pre, int st, ..., int lead, int limit) {
  if (pos > len) {
    return st;
  }
  if (!lead && !limit && dp[pos][pre][st]...) {
    return dp[pos][pre][st]...;
  }
  LL ret = 0;
  int res = limit ? a[len - pos + 1] : D - 1;
  for (int i = 0; i <= res; ++i) {
    if (lead && !i) {  //有前导0并且当前位也是前导0
      ret += dfs(len, pos + 1, 0, ..., 1, limit && i == res);
    } else if (lead && i) {  //有前导0但当前位不是前导0,当前位就是最高位
      ret += dfs(len, pos + 1, i, ..., 0, limit && i == res);
    } else if (...) {  //其他情况
      ret += dfs(len, pos + 1, i, ..., 0, limit && i == res);
    }
  }
  if (!lead && !limit) {
    dp[pos][pre][st]... = ret;
  }
  return ret;
}

LL part(LL x) {
  int len = 0;
  for (; x; x /= 10) {
    a[++len] = x % 10;
  }
  memset(dp, -1, sizeof dp);
  return dfs(len, 1, ..., 0, ..., 1, 1);
}

LL solve(LL l, LL r) {
  if (l) {
    return part(r) - part(l - 1);
  } else {
    return part(r) - part(l);
  }
}

发表回复

textsms
account_circle
email

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

immiq的博客

acm模板-数位dp
数位DP #define D 10 #define L 21 int a[L]; LL dp[L][D][]...; LL dfs(int len, int pos, int pre, int st, ..., int lead, int limit) { if (pos > len) { return st; } …
扫描二维码继续阅读
2022-04-14