很久以前做过的一道数位DP,现在用一种新的解决数位DP的比较一般的方法。

数位DP裸题是:求[L,R]有多少个数。

先转化成求[0,R]有多少个数,然后区间相减即可。

对于[0,R]中的所有数,用0补齐前面的空位,使得每个数的长度都为R的长度。

状态:

dp[pos][0]表示从最高位到pos位,没有顶上界的数的个数

dp[pos][1]表示从最高位到pos位,顶到上界的数的个数(好吧,这个问题中,它一定为1)

然后考虑转移,

dp[pos][0]->dp[pos-1][0](通过枚举pos-1位的数进行转移)

dp[pos][1]->dp[pos-1][0](通过枚举pos-1位,小于该位上界的数进行转移)

dp[pos][1]->dp[pos-1][1](只能在pos-1位填1)

顺推倒推都可以。

dp[1][0]+dp[1][1]就是答案。

对于其它的数位DP,都可以在这个DP上加上需要的状态维,然后解决其它问题。

上面的dp[pos][1]看似没有用(因为始终为1),但是实际上,我们是必须要它的,比如这道题。

我们设dp[pos][top][tail]表示:“比pos高的位,顶上界(top为1)或不顶上界(top为0),最后一位为tail的数的个数(并且要求这个数不为0)“

然后自己YY转移吧(这个不为0的要求和上一道题有点不同,具体看代码)。

新方法:

 /**************************************************************
Problem: 1026
User: idy002
Language: C++
Result: Accepted
Time:0 ms
Memory:808 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#define abs(a) ((a)>0?(a):-(a)) typedef long long poi; poi lf, rg;
int aa[], tot;
poi dp[][][]; poi calc( poi v ) { // v in [1,oo)
for( tot=; v; v/= )
aa[++tot]=v%;
memset( dp, , sizeof(dp) );
dp[tot][][aa[tot]] = ;
for( int i=; i<aa[tot]; i++ )
dp[tot][][i] = ;
for( int i=tot; i>=; i-- ) {
for( int c=; c<=; c++ )
for( int s=; s<=; s++ )
if( abs(s-c)>= )
dp[i-][][s] += dp[i][][c];
for( int s=; s<=; s++ )
dp[i-][][s]++;
for( int s=; s<aa[i-]; s++ )
if( abs(s-aa[i])>= )
dp[i-][][s] += dp[i][][aa[i]];
dp[i-][][aa[i-]] = dp[i][][aa[i]] && abs(aa[i]-aa[i-])>=;
}
poi rt=dp[][][aa[]];
for( int i=; i<=; i++ )
rt += dp[][][i];
return rt;
}
int main() {
scanf( "%lld%lld", &lf, &rg );
printf( "%lld\n", calc(rg)-(lf==?:calc(lf-)) );
}

以前的:

 /**************************************************************
Problem: 1026
User: idy002
Language: C++
Result: Accepted
Time:0 ms
Memory:804 kb
****************************************************************/ #include <cstdio>
#include <algorithm>
using namespace std; struct Form {
int n;
int b[];
int src;
Form( int a ) {
n = ;
src = a;
if( a== ) {
n=;
b[] = ;
return;
}
while( a ) {
b[++n] = a%;
a/=;
}
}
};
int dp[][]; // dp[0~9][0~10] void init() {
for( int h=; h<=; h++ )
dp[h][] = ;
for( int l=; l<=; l++ )
for( int h=; h<=; h++ )
for( int g=; g<=; g++ )
if( abs(g-h)>= )
dp[h][l] += dp[g][l-];
} int calc( const Form &fm) { // [0,fm.src)
int ans = fm.src!=; //
for( int l=; l<fm.n; l++ )
for( int h=; h<=; h++ ) {
ans += dp[h][l];
//printf( "(h=%d,l=%d)\n", h, l );
}
for( int h=; h<fm.b[fm.n]; h++ ) {
ans += dp[h][fm.n];
//printf( "(h=%d,l=%d)\n", h, fm.n );
}
for( int l=fm.n-; l>=; l-- ) {
for( int h=; h<fm.b[l]; h++ )
if( abs(h-fm.b[l+])>= ) {
ans += dp[h][l];
//printf( "(h=%d,l=%d)\n", h, l );
}
if( abs(fm.b[l]-fm.b[l+])< ) break;
}
return ans;
} int main() {
// freopen( "windy.in", "r", stdin );
// freopen( "windy.out", "w", stdout );
int A, B, ans;
init();
scanf( "%d%d", &A, &B );
ans = calc(Form(B+))-calc(Form(A));
printf( "%d\n", ans );
}

  

bzoj 1026的更多相关文章

  1. [BZOJ 1026] [SCOI 2009] Windy数 【数位DP】

    题目链接:BZOJ - 1026 题目分析 这道题是一道数位DP的基础题,对于完全不会数位DP的我来说也是难题.. 对于询问 [a,b] 的区间的答案,我们对询问进行差分,求 [0,b] - [0,a ...

  2. [bzoj 1026]windy数(数位DP)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1026 分析: 简单的数位DP啦 f[i][j]表示数字有i位,最高位的数值为j的windy数总 ...

  3. bzoj 1026 [SCOI2009]windy数 数位dp

    1026: [SCOI2009]windy数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...

  4. BZOJ 1026 windy数

    Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? In ...

  5. bzoj 1026 [SCOI2009]windy数(数位DP)

    1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4550  Solved: 2039[Submit][Sta ...

  6. BZOJ 1026: [SCOI2009]windy数( dp )

    dp..dp(x, t) 表示共x位, 第x位为t有多少个windy数. 对答案差分, 我们只需统计1 ~ l-1和1 ~ r的windy数数量. 考虑如何计算[1, n]的答案 : 从最高位到最低位 ...

  7. BZOJ 1026 windy数【数位DP】

    1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 10142  Solved: 4712[Submit][St ...

  8. bzoj 1026 DP,数位统计

    2013-11-20 08:11 原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1026 首先我们用w[i,j]表示最高位是第i位,且是j的 ...

  9. bzoj 1026: [SCOI2009]windy数【数位dp】

    忘记limit不能记WA了一发-- 典型数位dp,变成work(r)-work(l-1),然后dfs的时候记录w当前位置,la上一个数选的什么,lm当前位是否有上限,ok当前位是否可以不考虑差大于等于 ...

随机推荐

  1. Vue.js 在 webpack 脚手架中使用 cssnext

    Vue.js 的 webpack脚手架默认已经使用了 PostCSS 的 autoprefixer 的功能. 如果想使用下一代 css语法,即cssnext: 1. 安装依赖 npm install ...

  2. (3)剑指Offer之数值的整数次方和调整数组元素顺序

    一 数值的整数次方 题目描述: 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 问题解析: 这道题算是比较麻烦和难一点的一个了.我这里采 ...

  3. 夜神安卓模拟器adb命令详解

    https://www.yeshen.com/faqs/H15tDZ6YW 一.如何找到adb? 安装夜神安卓模拟器后,电脑桌面会有"夜神模拟器"的启动图标,鼠标右键--打开文件所 ...

  4. [转载]Windows服务编写原理及探讨(2)

    (二)对服务的深入讨论之上 上一章其实只是概括性的介绍,下面开始才是真正的细节所在.在进入点函数里面要完成ServiceMain的初始化,准确点说是初始化一个 SERVICE_TABLE_ENTRY结 ...

  5. 9.Python3标准库--数据压缩与归档

    ''' 尽管现代计算机系统的存储能力日益增长,但生成数据的增长是永无休止的. 无损(lossless)压缩算法以压缩或解压缩数据花费的时间来换取存储数据所需要的空间,以弥补存储能力的不足. Pytho ...

  6. day41 - 异步IO、协程

    目录 (见右侧目录栏导航) - 1. 前言- 2. IO的五种模型- 3. 协程    - 3.1 协程的概念- 4. Gevent 模块    - 4.1 gevent 基本使用    - 4.2 ...

  7. 次短路经(dijsktra)

    #include <cstdio>#include <cstring>#include <queue>#include <algorithm>#defi ...

  8. bug-bug-bug

    #-*-coding:utf-8-*- import urllib import urllib2 import re import json import threading import reque ...

  9. 这是我在word 2010上发布的第一篇文章

    1.设置word 2010,添加cnblogs帐户 配置参考链接 其中URL地址为: http://rpc.cnblogs.com/metaweblog/fariver,在cnblogs配置的最下方可 ...

  10. 常用 Java Profiling 工具的分析与比较

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-profiling/index.html 在 Java 程序的开发过程中,不可避免地会遇到内存使用. ...