首页 > 其他 > 详细

ABC 194 F.Digits Paradise in Hexadecimal

时间:2021-03-08 14:15:01      阅读:26      评论:0      收藏:0      [点我收藏+]

题意:给你一个数字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;
}

 

ABC 194 F.Digits Paradise in Hexadecimal

原文:https://www.cnblogs.com/Vikyanite/p/14498640.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!