题目链接:https://vjudge.net/problem/HDU-4734

题意:定义一个十进制数AnAn-1...A1的value为An*2n-1+...+A1*20,T组样例(<=1e4),每组样例给出a、b,求出[0,b]中value小于等于a的value的数的个数。

思路:数位dp,第一能想到将Ai*2i-1的和作为状态,即dp[len][sum]表示到长度为len的数中value为sum的数的个数,最后判断sum<=value(a)来确定是否满足条件。但是问题来了,我们会发现这样的状态与输入a相关,而输入有1e4组,时间限制为500ms,每次还都要memset(dp),显然会超时。

  这个时候就要优化,利用减法,dp[len][sum]表示长度len中value<=sum的数的个数,这一状态性质是所有数共有的性质,与输入a无关,因此可以保存dp的值,而不用memset,最后的结果就是递归到最后一层的sum>=0的数的个数,即value<=value(a)。

AC代码:

#include<cstdio>
#include<cstring>
using namespace std; int a[],dp[][],T; int gets(int x){
int k=,ret=;
while(x){
ret+=(<<k)*(x%);
x/=;
k++;
}
return ret;
} int dfs(int pos,int sum,bool limit){
if(pos==-) return ;
if(!limit&&dp[pos][sum]!=-) return dp[pos][sum];
int up=limit?a[pos]:;
int tmp=;
for(int i=;i<=up;++i){
int t=sum-(<<pos)*i;
if(t<) continue;
tmp+=dfs(pos-,t,limit&&i==a[pos]);
}
if(!limit) dp[pos][sum]=tmp;
return tmp;
} int solve(int x,int sum){
int pos=;
while(x){
a[pos++]=x%;
x/=;
}
return dfs(pos-,sum,true);
} int main(){
memset(dp,-,sizeof(dp));
scanf("%d",&T);
for(int i=;i<=T;++i){
int a,b,suma;
scanf("%d%d",&a,&b);
suma=gets(a);
printf("Case #%d: %d\n",i,solve(b,suma));
}
return ;
}

hdoj4734(数位dp优化)的更多相关文章

  1. [HDU4734] F(x)(数位dp+优化)

    >传送门<题意:对于一个有n位(这n位从高位到低位分别是An,An-1,An-2 ... A2,A1)的十进制数,我们定义它的权值F(x)=An*2n-1 + An-1*2n-2 + .. ...

  2. hdu 4734 F(x)(数位dp+优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4734 题意:我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2 ...

  3. 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化

    挺好的数位dp……先说一下我个人的做法:经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所有数 ...

  4. UOJ #86 mx的组合数 (数位DP+NTT+原根优化)

    题目传送门 matthew99神犇的题解讲得非常清楚明白,跪烂Orzzzzzzzzzzzzz 总结一下,本题有很多重要的突破口 1.Lucas定理 看到n,m特别大但模数特别小时,容易想到$lucas ...

  5. 浅谈数位DP

    在了解数位dp之前,先来看一个问题: 例1.求a~b中不包含49的数的个数. 0 < a.b < 2*10^9 注意到n的数据范围非常大,暴力求解是不可能的,考虑dp,如果直接记录下数字, ...

  6. hdu 3709 数位dp

    数位dp,有了进一步的了解,模板也可以优化一下了 题意:找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数例如4139,以3为支点4*2 ...

  7. 初探数位dp

    数位dp有着很明显的特点,一般来说是给定区间[l,r]求满足某种条件区间中的数有多少个 朴素解法一般是O(n)的而n往往很大(10^8起步) 这时候我们就要想办法优化,于是就有了数位dp 数位有两个基 ...

  8. 【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. 数位DP::SoSDP

    数位DP:: SoSDP 学习博客(待补) 下面做一些例题: SPECIAL PAIRS 题意 给n个数字,求这些数字有多少对的\(AND\) 结果是0.数字不大于1e6.顺序反相反视为不同的对. 思 ...

随机推荐

  1. oracle query

    不等值连接查询 员工工资级别 select e.empno,e.ename,e.sal,s.grade from emp e,salgrade s where e.sal between s.losa ...

  2. java 中异常处理示例并捕获完整异常内容

    public class Test { public static void main(String[] args) { try { int a = 1; int b = 0; int c = a/b ...

  3. telnet服务搭建

    Telnet服务器安装(centos7系统环境) 查看系统是否已安装telnet rpm -qa | grep telnettelnet-0.17-48.el6.x86_64telnet-server ...

  4. Go并发编程实战 (郝林 著)

    第1章 初识Go语言 1.1 语言特性 1.2 安装和设置 1.3 工程构造 1.3.1 工作区 1.3.2 GOPATH 1.3.3 源码文件 package main import ( " ...

  5. [ZZ] 麻省理工( MIT)大神解说数学体系

    麻省理工( MIT)大神解说数学体系 http://blog.sina.com.cn/s/blog_5ff4fb7b0102e3p6.html 其实每一门学科都应该在学习完成后,在脑子里面有一个体系, ...

  6. Azure VMSS (2) 对VM执行Generalize操作

    <Windows Azure Platform 系列文章目录> 在本章中,笔者将介绍如何创建Azure Template镜像模板. 1.首先,我们先创建1台Windows Server 2 ...

  7. mysql识别中文

    在配置的INI中加上这些 [mysql]default-character-set=utf8no-auto-rehash# Remove the next comment character if y ...

  8. 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) ...ubuntu 18.04 安装vim遇到的错误

    安装vim: sudo apt-get install vim-gtk 问题: E:无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E:无法锁定管理目录(/ ...

  9. iOS上传本地代码到git

    1.顾名思义,首先你得注册一个github账户 这个我就不细说了. 2.然后你得创建一个 repository  步骤见下图 3.相当于创建成功 会跳到下图界面 4.一看就很清楚了 create a ...

  10. 5、Zookeeper命令操作

    一.Zookeeper的四字命令 Zookeeper支持某些特定的四字命令字母与其的交互.他们大多数是查询命令,用来获取Zookeeper服务的当前状态及相关信息.用户在客户端可以通过telnet或n ...