hdu5787 数位dp 数位压缩

来源:互联网 发布:windows密码破解工具 编辑:程序博客网 时间:2024/06/06 22:40

分析
大概是比较经典的数位dp,需要维护连续的k个数字不相同,所以我们的状态记录里需要记录前k1个数字是哪些,扩展下一位的时候不能出现前k1位的数字。
这样就来设计状态:dp[len][k][ban],表示前长度为len,连续的k个字符禁止出现相同,前k1个数字为ban
这里的ban用了数字压缩的技巧,比如前3个数字为4,2,5,那么我的ban就是10进制数425
到这里赛场上都很容易想到,但是由于处理前到零一直debug了我4个小时才对,还增加了一个维度作为记录连续的多少位内禁止出现0
一言不合就加维度!

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;typedef pair<int, int> pii;typedef long long ll;typedef unsigned long long ull;vector<int> vi;#define pr(x) cout << #x << ": " << x << "  " #define pl(x) cout << #x << ": " << x << endl#define xx first#define yy second#define sa(n) scanf("%d", &(n))#define rep(i, a, n) for (int i = a; i < n; i++)#define vep(c) for(decltype((c).begin() ) it = (c).begin(); it != (c).end(); it++) #define limit asdfconst int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;int T;ll dp[19][4][9876 + 7][5];int bits[25];ll l, r;int k;ll dfs(int len, int ban, bool limit, int k, int go, int zero, bool pre) {    if (len == 0) return 1;    if (!pre && !limit && dp[len][k - 2][ban][zero] != -1) return dp[len][k - 2][ban][zero];    int m = limit ? bits[len] : 9;    ll ret = 0;    bool no[10];    memset(no, 0, sizeof(no));    int t = ban;    for (int i = 0; t; ++i) {        no[t % 10] = true;        t /= 10;    }    if (!pre && zero > 0) no[0] = true;    for (int i = 0; i <= m; i++) {        if (no[i]) continue;        int nxt = ban % (int)pow(10, k - 2);         nxt = nxt * 10 + i;        int nxtzero = zero;        if (!pre) {            if (!i) nxtzero = k - 1;            else nxtzero--;            if (nxtzero < 0) nxtzero = 0;        }         ret += dfs(len - 1, nxt, limit && i == m, k, go + 1, nxtzero, pre && !i);    }    if (!pre && !limit) dp[len][k - 2][ban][zero] = ret;    return ret;}//常规套路ll solve(ll n) {    ll key = n, t = 1;    while (key) {        bits[t++] = key % 10;        key /= 10;    }    ll ret = dfs(t - 1, 0, true, k, 0, 0, true);    return ret;}int main(void){#ifdef LOCAL    freopen("in.txt", "r", stdin);   // freopen("out.txt", "w", stdout);#endif    memset(dp, -1, sizeof(dp));    while (~scanf("%lld%lld%d", &l, &r, &k)) {        printf("%lld\n", solve(r) - solve(l - 1));    }    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 胶水粘到手机上怎么办 沾鞋胶水粘到手怎么办 轮胎内衬板坏了怎么办 轿车后减震异响怎么办 租的房间隔音差怎么办 彩钢房顶下雨响怎么办 酷派手机开不开机怎么办 酷派手机无法开机怎么办 酷派手机丢了怎么办 实木家具掉漆了怎么办 木桌子上有划痕怎么办 烤漆家具掉漆怎么办 洗碗帕沾了油污怎么办 手被棍子打肿了怎么办 楼上弄的声音大怎么办 楼上太吵楼下人怎么办 严重多囊卵巢该怎么办 被医院骗了应该怎么办 四维胎儿不配合怎么办 孕甲状腺tsh有点偏高怎么办 20岁得胃癌了怎么办 洗鼻涕耳朵堵了怎么办 胡振兴预约不上怎么办 玻尿酸打歪了怎么办 隆鼻后鼻子胀疼怎么办 鼻子做的太高了怎么办 感觉被医院骗了怎么办 中风后嘴巴歪了怎么办 孩子中风嘴歪了怎么办 胃疼怎么办简单的偏方 胃痛怎么办简单有效的方法 急用5000元怎么办又没信用卡 我真的不想活了怎么办 不想活了怎么办很累 毕业推荐表丢了怎么办 想去英国留学该怎么办 三个人跟团住宿怎么办 跟团被强制消费怎么办 苹果6s手机黑屏怎么办 胸闷喘不过气来怎么办 经常胸闷气短呼吸困难怎么办