BZOJ1833或洛谷2602 [ZJOI2010]数字计数

BZOJ原题链接

洛谷原题链接

又是套记搜模板的时候。。
\(0\sim 9\)单独统计。
定义\(f[pos][sum]\),即枚举到第\(pos\)位,前面枚举的所有位上是当前要统计的数的个数之和为\(sum\)

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 13;
ll f[N][N];
int a[N], nw;
inline ll re()
{
    ll x = 0;
    char c = getchar();
    bool p = 0;
    for (; c < '0' || c > '9'; c = getchar())
        p |= c == '-';
    for (; c >= '0' && c <= '9'; c = getchar())
        x = x * 10 + c - '0';
    return p ? -x : x;
}
ll dfs(int pos, int s, int lm, int zero)
{
    if (pos < 0)
        return s;
    if (!lm && !zero && f[pos][s] > -1)
        return f[pos][s];
    int i, k = lm ? a[pos] : 9;
    ll S = 0;
    for (i = 0; i <= k; i++)
        S += dfs(pos - 1, s + ((!nw && !i && !zero) || (nw && i == nw)), lm && i == a[pos], zero && !i);
    if (!lm && !zero)
        return f[pos][s] = S;
    return S;
}
ll calc(ll x)
{
    int k = 0;
    memset(f, -1, sizeof(f));
    while (x > 0)
    {
        a[k++] = x % 10;
        x /= 10;
    }
    return dfs(k - 1, 0, 1, 1);
}
int main()
{
    ll x, y;
    x = re();
    y = re();
    for (nw = 0; nw <= 9; nw++)
        printf("%lld ", calc(y) - calc(x - 1));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Iowa-Battleship/p/9726425.html