zoukankan      html  css  js  c++  java
  • P2657 [SCOI2009]windy数

    P2657 [SCOI2009]windy数


    题目描述

    windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,

    在A和B之间,包括A和B,总共有多少个windy数?


    数位dp

    状态设计为(f[i][j])最高位为(j),已经有了(i)位的数。所能构成的windy数

    然后先使用打出一个表来,在进行拼接(废话么不是

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    const int maxn=12;
    int f[maxn][maxn];
    int work(int val)
    {
        if(val==0)  return 0;
        int k=0,base[maxn]={0};
        int res=0;
        while(val)
        {
            base[++k]=val%10;
            val/=10;
        }//先按照位数拆出来
        for(int i=k-1;i>=1;i--)
            for(int j=1;j<=9;j++)
                res+=f[i][j];//所有位数比val小的都加进答案
        for(int i=1;i<base[k];i++)
            res+=f[k][i];//预处理第一位
        for(int i=k-1;i>=1;i--)
        {
            for(int l=0;(l<base[i]&&i>1)||(i==1&&l<=base[i]);l++)//开始拼接
                if(abs(base[i+1]-l)>=2)//判断是否和前一位符合条件
                    res+=f[i][l];//累加
            if(abs(base[i+1]-base[i])<2)    break;//val本身不满足条件了,就退出循环
        }
        return res;
    }
    int main()
    {
        int l,r;
        scanf("%d%d",&l,&r);
        for(int i=0;i<=9;i++)
            f[1][i]=1;
        for(int i=2;i<=10;i++)
            for(int j=0;j<=9;j++)
                for(int k=0;k<=9;k++)
                    if(abs(j-k)>=2)
                        f[i][k]+=f[i-1][j];//打表
        printf("%d",work(r)-work(l-1));//前缀和
        return 0;
    }
    
    
  • 相关阅读:
    mysql学习笔记-数据库相关操作
    bugku-flag在index里(本地文件包含漏洞+php伪协议的结合应用)
    nmap的指令学习
    雅礼2018-03-11
    两道题,雅礼一题矩阵转置
    2018-03-05 计算鞍点
    多维数组
    TCP拥塞控制
    TCP三次握手和四次挥手
    MySQL事务隔离级别详解
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9721142.html
Copyright © 2011-2022 走看看