zoukankan      html  css  js  c++  java
  • [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();
    }
    
  • 相关阅读:
    HTML JS 数据校验
    算法: 实现LRU缓存,读取、写入O(1)实现
    C/C++ 二维数组
    tmux 终端分屏利器使用
    关于Apache Tomcat存在文件包含漏洞的安全公告
    SQLSERVER触发器触发INSERT,UPDATE,DELETE三种状态
    SQL Server 触发器
    SQL Server游标
    SQL Server基础之游标
    阿里maven镜像配置
  • 原文地址:https://www.cnblogs.com/mollnn/p/14563437.html
Copyright © 2011-2022 走看看