acm模板-数位dp

发布于 2022-04-14  2348 次阅读


数位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);
  }
}
Hello, world!
最后更新于 2022-04-14