前言

最近学了数位DP,感觉挺简单又实用。这道题就比较水,可以用300B的贪心过掉…网上似乎大多是贪心的题解,我就写写DP的做法


题意

  • 给出正整数区间[L,R][L,R][L,R],定义荒谬值为 (去掉后导零的数的长度)*2-[去掉后导零之后末位为5]。求荒谬值最小的数。若有多个则输出最小值。
  • 状态定义为 (i,s,cnt0,flg,fl,fr)(i,s,cnt0,flg,f_l,f_r)(i,s,cnt0,flg,fl​,fr​)
    • int iint\ iint i:表示当前在第 iii 位(最低位为 111 )
    • int jint\ jint j:有效长度为 sss,即从第一个非零位开始记的长度
    • int cnt0int\ cnt0int cnt0:末尾有几个零
    • bool flgbool\ flgbool flg:去掉后导零之后末位是否为 555
    • bool frbool\ f_rbool fr​:是否达到下限
    • bool frbool\ f_rbool fr​:是否达到上限
  • 这里的 fl,frf_l,f_rfl​,fr​ 是数位DP常用的限制数字大小的方法
  • 因为既要保证荒谬值,又要答案最小,就用一个结构体存下荒谬值和对应的最小答案就行了。转移十分简单。因为数的长度最大为 101010,状态数为O(10∗10∗10∗2∗2∗2)=O(8000)O(10*10*10*2*2*2)=O(8000)O(10∗10∗10∗2∗2∗2)=O(8000)
  • 要注意每次都要清零,因为即使 状态一样且没有达到上限或者下限 的时候最小答案也会受[L,R][L,R][L,R]的影响 (没看懂的先看代码,再看下面的UpdUpdUpd)
  • 还有注意存LLL、RRR的数组也要清零

AC代码

#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9+1;
struct node {
int x, y;
node(int _x=0, int _y=0):x(_x), y(_y){}
inline node operator +(const node &t)const {
if(x < t.x) return *this;
if(x > t.x) return t;
return node(x, min(y, t.y));
}
};
node f[11][11][11][2];
bool vis[11][11][11][2];
int dl[11], dr[11]; inline node dfs(int len, int s, int cnt0, bool flg, bool fl, bool fr, int tmp) {
if(!len) return node((flg ? 2*(s-cnt0)-1 : 2*(s-cnt0)), tmp);
if(!fl && !fr && vis[len][s][cnt0][flg]) return f[len][s][cnt0][flg];
node res = node(inf, inf);
int mn = fl ? dl[len] : 0, mx = fr ? dr[len] : 9;
for(int i = mn; i <= mx; ++i)
res = res + dfs(len-1, s+(s||i), i?0:cnt0+1, i ? i==5: flg, fl&&i==mn, fr&&i==mx, tmp*10+i);
if(!fl && !fr) {
vis[len][s][cnt0][flg] = 1;
f[len][s][cnt0][flg] = res;
}
return res;
} inline int solve(int l, int r) {
memset(dl, 0, sizeof dl); //清零2
memset(dr, 0, sizeof dr);
int lenl = 0, lenr = 0;
while(l) dl[++lenl] = l % 10, l /= 10;
while(r) dr[++lenr] = r % 10, r /= 10;
node res = dfs(lenr, 0, 0, 0, 1, 1, 0);
return res.y;
}
int L, R;
int main () {
int T;
scanf("%d", &T);
while(T--) {
memset(vis, 0, sizeof vis); //清零 1 (让我WA到自闭)
scanf("%d%d", &L, &R);
printf("%d\n", solve(L, R));
}
}

Upd:Upd:Upd:之所以会受影响,是因为我算答案的时候,带入了tmptmptmp计算。第一次进去的时候能保证数答案在[L,R][L,R][L,R]内,但如果记忆化后[L,R][L,R][L,R]改变了,就不能保证在区间里面。

BZOJ 4029 [HEOI2015] 定价 ( 数位DP/贪心 )的更多相关文章

  1. BZOJ 4029 HEOI2015 定价 数位贪心

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4029 题意概述:对于一个数字的荒谬程度定义如下:删除其所有的后缀0,然后得到的数字长度为a ...

  2. BZOJ 4029: [HEOI2015]定价 贪心

    4029: [HEOI2015]定价 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4029 Description 在市场上有很多商品的 ...

  3. BZOJ 4029 [HEOI2015]定价

    题解: !!!!!! 分类讨论,情况挺多 #include<iostream> #include<cstdio> #include<cstring> using n ...

  4. BZOJ 3652: 大新闻(数位DP+概率论)

    不得不说数位DP和博弈论根本不熟啊QAQ,首先这道题嘛~~~可以分成两个子问题: 有加密:直接算出0~n中二进制每一位为0或为1分别有多少个,然后分位累加求和就行了= = 无加密:分别算出0~n中二进 ...

  5. BZOJ 1833 数字计数 数位DP

    题目链接 做的第一道数位DP题,听说是最基础的模板题,但还是花了好长时间才写出来..... 想深入了解下数位DP的请点这里 先设dp数组dp[i][j][k]表示数位是i,以j开头的数k出现的次数 有 ...

  6. BZOJ 4521 [CQOI2016]手机号码 - 数位DP

    Description 在$[L, R]$找出有几个数满足两个条件 : 1 : 不同时含有$4$ 和 $8$ 2 : 至少有$3$个相邻的数相同 Solution 非常容易的数位DP, $pos$ 为 ...

  7. BZOJ 3131 [SDOI2013]淘金 - 数位DP

    传送门 Solution 这道数位$DP$看的我很懵逼啊... 首先我们肯定要先预处理出 $12$位乘起来的所有的可能情况, 记录入数组 $b$, 发现个数并不多, 仅$1e4$不到. 然后我们考虑算 ...

  8. BZOJ 1799 同类分布(数位DP)

    给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1<=a<=b<=1e18. 注意到各位数字之和最大是153.考虑枚举这个东西.那么需要统计的是[0,a-1]和[0,b ...

  9. bzoj 3329: Xorequ【数位dp+矩阵乘法】

    注意第一问不取模!!! 因为a+b=a|b+a&b,a^b=a|b-a&b,所以a+b=a^b+2(a&b) x^3x==2x可根据异或的性质以转成x^2x==3x,根据上面的 ...

随机推荐

  1. java23种设计模式之九: 抽象工厂方法模式

    一.抽象工厂定义 上一讲我们说了一下工厂方法,那么我们如何对工厂进行抽象. 因为工厂是生产产品的,现在我们需要工厂抽象,只生产抽象产品,不生产具体的产品,这同时也体现了java的多态. 现在有2个抽象 ...

  2. [转帖]详解shell脚本括号区别--$()、$「 」、$「 」 、$(()) 、「 」 、「[ 」]

    详解shell脚本括号区别--$().$「 」.$「 」 .$(()) .「 」 .「[ 」] 原创 波波说运维 2019-07-31 00:01:00 https://www.toutiao.com ...

  3. Oracle数据库——查询所有用户

    查询数据库所有用户(ALL_USERS)的用户名,用户编号,创建日期 默认应该有36个用户 SELECT * FROM ALL_USERS; 查看ALL_USERS的结构 DESC ALL_USERS ...

  4. 【全排列+子序列】Color

    [题意] 这个题目就是问,是否存在每个人对应每一种颜色,如果存在则输出字典序最小的. 否则输出-1 [题解] 利用next_permutation来构造36种情况.记住最后还需要排序一遍. 然后用子序 ...

  5. Sonya and Bitwise OR CodeForces - 1004F (线段树,分治)

    大意: 给定序列$a$, 给定整数$x$. 两种操作(1)单点修改 (2)给定区间$[l,r]$,求有多少子区间满足位或和不少于$x$. 假设不带修改. 固定右端点, 合法区间关于左端点单调的. 可以 ...

  6. 轻松搭建CAS 5.x系列(9)-登录后显示通知信息

    概述说明 用户在账号名密码认证通过后,CAS可以跳转到登陆完成页面前,显示相关的通知页面. 搭建步骤 `1. 首先,您需要有个CAS Server端 如果您没有,可以按照我之前写的文章<轻松搭建 ...

  7. html如何点击子元素事件而不触发父元素的点击事件——阻止冒泡

    如果子元素和父元素都有点击事件,会出现点击事件冒泡的情况. 1.如何避免冒泡: html: <html> <head></head> <body> &l ...

  8. SQL logic error no such module: fts5 解决方案

    因项目原因,需要使用SQLite的全文索引,用到了最新的fts5模块 但在咱们.net framwork中却会提示“SQL logic error no such module: fts5”:找不到f ...

  9. 排序算法原理及代码实现(c#)

    1.插入排序 把第一个元素看做已排序数组放在有序数组中,从第二个元素开始,依次把无序数组元素取出和有序数组中的元素逐个比较,并放在有序数组的正确位置上. /// <summary> /// ...

  10. Python考试_第三次

    - python 全栈11期月考题 一 基础知识:(70分) 1.文件操作有哪些模式?请简述各模式的作用(2分) 2.详细说明tuple.list.dict的用法,以及它们的特点(3分) 3.解释生成 ...