ABC 194 F.Digits Paradise in Hexadecimal

题意:给你一个数字n,让你求1-n之间,十六进制下恰好有k个不同数字的数有几个。

思路:一眼就看出了是数位dp。但是没有仔细去想非常的遗憾。赛后发现其实只需要用一个16位的01串去表示这个数字有没有被用过就行了。

个人喜欢用记忆化搜索写数位dp。给出dp数组。dp[16位的01串][当前枚举数位][是否有前导0][是否满足大小限制]

复制代码
#include <bits/stdc++.h>
#define DEBUG if(0)
typedef long long ll;
using namespace std;

const int maxSz = 2e5, maxCnt = 16;
const ll mod = 1e9 + 7;
ll dp[maxSz][maxCnt + 1][2][2];

char s[maxSz + 1];
int a[maxSz];
int sz, k;

ll solve(int state, int pos, bool lmt, bool lead) {
    int cnt = __builtin_popcount(state);
    if (cnt > k) return 0;
    if (pos == sz) return cnt == k && lead;

    ll &ans = dp[pos][cnt][lmt][lead];
    if (ans != -1) return ans;

    ans = 0;
    int llmt = (lmt ? a[pos] : 15);
    for (int i = 0; i <= llmt; i++)
        ans = (ans + solve((!i && !lead) ? state : state | (1 << i), pos + 1, lmt & (i == llmt), lead | i)) % mod;
    return ans;
}

int main() {
    cin >> s >> k;
    sz = strlen(s);
    for (int i = 0; i < sz; i++) {
        a[i] = s[i] - (isdigit(s[i]) ? '0' : 'A' - 10);
    }
    memset(dp, -1, sizeof(dp));
    cout << solve(0, 0, 1, 0) << endl;

  return 0;
}
复制代码

 

posted @   ViKyanite  阅读(246)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示
主题色彩