[CF96E] Horse Races

[CF96E] Horse Races - 数位dp

Description

给定区间 ([l,r]),求区间内有多少个数满足其中存在幸运数字,并且至少有两个幸运数字相差的位数不超过 (k)

Solution

数位 dp,设 (f(pos,lim,last,flag)) 表示从高到低处理到了第 (pos) 位,当前是否顶格,上一位幸运数字在 (last) 位置,当前是否已经满足条件

转移的时候,对于当前位是幸运数字和不是幸运数字的情况,分别处理即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int mod = 1e9 + 7;

int a[1005], f[1005][2][2005][2], n, k;

int dfs(int pos, int lim, int last, int flag)
{
    if (pos < 0)
    {
        return flag;
    }
    auto &ans = f[pos][lim][last][flag];
    if (~ans && !lim)
        return ans;
    ans = 0;
    int up = lim ? a[pos] : 9;
    for (int i = 0; i <= up; i++)
    {
        if (i == 4 || i == 7)
        {
            ans += dfs(pos - 1, lim && (i == a[pos]), pos, flag || (last - pos <= k));
        }
        else
        {
            ans += dfs(pos - 1, lim && (i == a[pos]), last, flag);
        }
        ans %= mod;
    }
    return ans;
}

int solve(int flag)
{
    string str;
    cin >> str;
    for (int i = 0; i < str.size(); i++)
        a[str.size() - 1 - i] = str[i] - '0';

    int res = 0;
    if (flag)
    {
        set<int> s;
        for (int i = 0; i < str.size(); i++)
            if (str[i] == '4' || str[i] == '7')
                s.insert(i);
        for (auto i : s)
        {
            auto t = s.upper_bound(i);
            if (t != s.end())
                if (*t - i <= k)
                    res = 1;
        }
    }
    return (dfs(str.size() - 1, 1, str.size() + k, 0) - res + mod) % mod;
}

void group()
{
    int a1 = solve(1);
    int a2 = solve(0);
    cout << (a2 - a1 + mod) % mod << endl;
}

signed main()
{
    ios::sync_with_stdio(false);

    memset(f, -1, sizeof f);

    int t;
    cin >> t >> k;
    while (t--)
        group();
}
原文地址:https://www.cnblogs.com/mollnn/p/14563437.html