传送门

md直接wa了78次,身败名裂

没学过数位DP硬搞了一道数位DP的模板题,感觉非常的愉(sha)悦(cha)。

二分转化枚举思想。首先DP预处理出来$f[i][j]$表示有$i$位且第$i$位为$j$的windy数有多少个,然后搞个$g[i]$表示$i$位上可以有多少个windy数。然后二分出来最大的小于$A$和$B$的windy数。相减就好了。

//BZOJ 1026
//by Cydiater
//2016.10.24
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <iomanip>
#include <bitset>
using namespace std;
#define ll long long
#define up(i,j,n)       for(int i=j;i<=n;i++)
#define down(i,j,n)     for(int i=j;i>=n;i--)
const int oo=0x3f3f3f3f;
inline ll read(){
    char ch=getchar();ll x=0,f=1;
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
ll f[15][15],A,B,g[15],ten[15];
namespace solution{
    void init(){
        A=read();B=read();
        ll tmp=1;
        up(i,1,14){
            ten[i]=tmp;
            tmp*=10LL;
        }
    }
    ll col(ll pos,ll re,ll last){
        if(pos==0)return 0;
        if(last==-1){
			if(pos==1){
				if(re<=f[pos][0])return 0;
				re-=f[pos][0];
			}
            up(i,1,9){
                if(re<=f[pos][i])return  ten[pos]*i+col(pos-1,re,i);
                re-=f[pos][i];
            }
        }else{
			if(pos==1&&last-2>=0){
				if(re<=f[pos][0])return 0;
				re-=f[pos][0];
			}
            if(last-2>=0){
                ll sum=0;
                up(i,2,9)sum+=f[pos-1][i];
                if(re<=sum)      return col(pos-1,re,0);
                else            re-=sum;
            }
            up(i,1,9)if(abs(i-last)>=2){
                if(re<=f[pos][i])    return ten[pos]*i+col(pos-1,re,i);
                re-=f[pos][i];
            }
        }
    }
    ll check(ll id){
        ll last=-1,ans=0,high=0;
        down(i,11,1)if(g[i]<id){
            high=i;
            id-=g[i];
            break;
        }
        ans=col(high+1,id,-1);
        return ans;
    }
    ll get(ll num){
        ll leftt=0,rightt=10000000000LL,mid;
        while(leftt+1<rightt){
            mid=(leftt+rightt)>>1;
            if(check(mid)<=num)   leftt=mid;
            else                rightt=mid;
        }
        if(check(rightt)<=num)       return rightt;
        return leftt;
    }
    void slove(){
        memset(f,0,sizeof(f));
        up(i,0,9)f[1][i]=1;
        up(i,2,14)up(j,0,9){
            up(k,j+2,9)f[i][j]+=f[i-1][k];
            down(k,j-2,0)f[i][j]+=f[i-1][k];
        }
		if(A>B)swap(A,B);
        memset(g,0,sizeof(g));
        g[0]=1;
        up(i,1,14){
            g[i]+=g[i-1];
            up(j,1,9)g[i]+=f[i][j];
        }
        cout<<get(B)-get(A-1)<<endl;
    }
}
int main(){
	//freopen("input.in","r",stdin);
	//freopen("out1.out","w",stdout);
    using namespace solution;
    init();
    slove();
    return 0;
}

BZOJ1026: [SCOI2009]windy数的更多相关文章

  1. BZOJ1026 SCOI2009 windy数 【数位DP】

    BZOJ1026 SCOI2009 windy数 Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B ...

  2. BZOJ1026: [SCOI2009]windy数[数位DP]

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

  3. 【数位DP】bzoj1026: [SCOI2009]windy数

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

  4. bzoj1026: [SCOI2009]windy数(数位dp)

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

  5. 2018.06.30 BZOJ1026: [SCOI2009]windy数(数位dp)

    1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MB Description windy定义了一种windy数.不含前导零且相邻两 ...

  6. bzoj千题计划117:bzoj1026: [SCOI2009]windy数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1026 数位DP 如果前一位填的是0, 0是前导0,下一位可以随便填 0不是前导0,下一位不能填1 为 ...

  7. bzoj1026: [SCOI2009]windy数(传说你是数位DP)

    1026: [SCOI2009]windy数 题目:传送门 题解: 其实之前年少无知的时候好像A过...表示当时并不知道什么数位DP 今天回来深造一发... 其实如果对这个算法稍有了解...看到这题的 ...

  8. [bzoj1026][SCOI2009]windy数_数位dp

    windy数 bzoj-1026 题目大意:求一段区间中的windy数个数. 注释:如果一个数任意相邻两位的差的绝对值都不小于2,这个数就是windy数,没有前导0.$区间边界<=2\cdot ...

  9. [BZOJ1026][SCOI2009]windy数 解题报告|数位dp

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

随机推荐

  1. Java:Remote Debug

    Java  Remote Debug -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,add ...

  2. PHP服务缓存优化之ZendOpcache、xcache、eAccelerator

    PHP服务缓存优化原理 Nginx 根据扩展名或者过滤规则将PHP程序请求传递给解析PHP的FCGI,也就是php-fpm进程 缓存操作码(opcode) Opcode,PHP编译后的中间文件,缓存给 ...

  3. shell实现SSH自动登陆

    h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h ...

  4. sql server之ROW_NUMBER() OVER()取每组的第N行数据

    先看个例子: document_id card_holder_id created_date document_type_id 1 1 2015-7-1 1 2 4 2015-7-2 1 3 4 20 ...

  5. CPU 和内存虚拟化原理 - 每天5分钟玩转 OpenStack(6)

    前面我们成功地把 KVM 跑起来了,有了些感性认识,这个对于初学者非常重要.不过还不够,我们多少得了解一些 KVM 的实现机制,这对以后的工作会有帮助. CPU 虚拟化 KVM 的虚拟化是需要 CPU ...

  6. freeradius + oracle 无限认证

    Radius安装配置维护文档 一.下载软件包 freeradius-server-3.0.9.tar.gz和talloc-2.1.3.tar.gz 二.配置/root目录下的.bash_profile ...

  7. Navicat安装详解

    本文章介绍MySql图形化操作软件Navicat的安装 属于PHP环境搭建的一部分. PHP完整配置信息请参考 http://www.cnblogs.com/azhe-style/p/php_new_ ...

  8. .Net 扩展方法集合.

      在项目中很多时候都会对字符串和集合做特定的处理.而且很多地方都会去调用.为了解决这些问题.我们通常会在项目中吧这些方法提成公共方法.下面是自己总结的项目中用到的一些扩展方法.封装成了一个Libra ...

  9. MMORPG大型游戏设计与开发(服务器 游戏场景 搜索机)

    双十一注定是忙碌的日子,所以到了现在我才将今天自己学习的内容拿出来跟大家分享.搜索机是我自己暂时取的名字,其实简单的说就是场景里提供搜索的一个工具,负责场景对象的范围搜索和获取.空洞的理论总是让人一头 ...

  10. Html文档流和文档对象模型DOM理解

    前言 在理解浮动和定位时,触碰到文档流概念.为了更好理解浮动和定位,学习了文档流和DOM(文档对象模型). 正文 DOM(文档对象模型)简单理解就是编写的html页面所有内容构成的树形结构.例如: 根 ...