• 【luogu2657】【bzoj1026】 [SCOI2009]windy数 [动态规划 数位dp]


    P2657 [SCOI2009]windy数

    bzoj1026 

    一本通说这是一道数位dp模板题 emmmmm 就是逐位确定

    f[i][j]表示填了i位数其最高位数字为j 然后就去求可能方案数

    分为

    • 不满足x的位数的严格小于x的全部情况
    • 和x的位数相同 但最高位小于x的最高为的全部方案数
    • 和x的位数相同 有一位比x的对应位数小的全部方案数 其余位数对应数字都相同(这是数位dp常用的一个性质:对于一个小于n的数 它从高位到低位一定会出现某一位上的数字小于n所对应这一位上的数字)

    PS 因为x不一定为windy数 所以在第三种方案时 我们遇到不满足为windy数时退出

    只是我还没搞懂为什么输出dp(b)-dp(a-1)会错一个点

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<stack>
     7 #include<algorithm>
     8 using namespace std;
     9 #define ll long long
    10 #define rg register
    11 const int N=2000000000+5,pw=11,inf=0x3f3f3f3f,P=19650827;
    12 int a,b,f[pw+5][pw+5];
    13 ll base[pw+5];
    14 template <class t>void rd(t &x)
    15 {
    16     x=0;int w=0;char ch=0;
    17     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    18     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    19     x=w?-x:x;
    20 }
    21 
    22 void prepare()
    23 {
    24     base[0]=1;
    25     for(rg int i=1;i<=pw;++i) base[i]=base[i-1]*10;
    26     for(rg int i=0;i<10;++i) f[1][i]=1;//
    27     for(rg int i=2;i<=pw;++i)
    28     for(rg int j=0;j<10;++j)
    29     for(rg int k=0;k<10;++k)
    30     if(abs(j-k)>=2) f[i][j]+=f[i-1][k]; 
    31 }
    32 
    33 int dp(int x)
    34 {
    35     int p,ans=0;
    36     for(p=0;p<=pw;++p) if(base[p]>x) break;
    37     if(!p) return ans; 
    38     for(rg int i=1;i<p;++i)
    39     for(rg int j=1;j<10;++j)
    40     ans+=f[i][j];//不满p位的
    41     int pre=x/base[p-1];x%=base[p-1];
    42     for(rg int i=1;i<pre;++i)
    43     ans+=f[p][i];//满足p位 但第p位数字小于x的
    44     for(rg int i=p-1;i>0;--i)
    45     {
    46         int cur=x/base[i-1];
    47         for(rg int j=0;j<cur;++j)
    48         if(abs(pre-j)>=2) ans+=f[i][j];
    49         if(abs(pre-cur)<2) break; 
    50         pre=cur,x%=base[i-1];
    51      } 
    52      return ans;
    53 }
    54 
    55 int main()
    56 {
    57     //freopen("in.txt","r",stdin);
    58     //freopen("nocows.out","w",stdout);
    59     prepare();
    60     rd(a),rd(b);
    61     printf("%d",dp(b+1)-dp(a));
    62     return 0;
    63 }
  • 相关阅读:
    4. Qt的容器类
    hdu 4507 数位dp(求和,求平方和)
    MVC3和MVC4中CRUD操作
    SSL 中证书能否够使用IP而不是域名
    TinyXml快速入门(一)
    C++ TinyXml操作(含源码下载)
    Tinyxml 操作XML
    msxml 操作xml
    MFC中全局变量的定义及使用
    VC++中操作XMLWin32实例
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/10917314.html
Copyright © 2020-2023  润新知