zoukankan      html  css  js  c++  java
  • bzoj1026: [SCOI2009]windy数(数位dp)

    1026: [SCOI2009]windy数

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 7812  Solved: 3522
    [Submit][Status][Discuss]

    Description

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

    Input

      包含两个整数,A B。

    Output

      一个整数

    Sample Input

    【输入样例一】
    1 10
    【输入样例二】
    25 50

    Sample Output

    【输出样例一】
    9
    【输出样例二】
    20

    HINT

     

    【数据规模和约定】

    100%的数据,满足 1 <= A <= B <= 2000000000 。

    思路:http://blog.csdn.net/zz_ylolita/article/details/50754618

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    
    using namespace std;
    
    int dig[12];
    int f[12][10];
    //f[i][j]代表长度为i,最高位为j的windy数个数
    
    void init()
    {
       memset(f,0,sizeof(f));
       for(int i=0;i<10;i++) f[1][i] = 1;
       for(int i=2;i<=10;i++)
        for(int j=0;j<10;j++)
          for(int k=0;k<10;k++)
            if(abs(j-k)>1) f[i][j] += f[i-1][k];
    }
    //(0,dig)范围内的windy数个数
    int solve(int x)
    {
       int len=0;
       while(x)
       {
          dig[len++]=x%10;
          x/=10;
       }
       int ans=0;
       //先处理长度小于len的windy数的个数
       for(int i=1;i<len;i++)
         for(int j=1;j<10;j++)//题目要求不含前导0
            ans+=f[i][j];
       for(int j=1;j<dig[len-1];j++) //长度等于len且最高位和原数不同且小于原数的windy数
         ans+=f[len][j];
       for(int i=len-1;i>=1;i--)//依次循环将最高位变为和原数相同
       {
          for(int j=0;j<dig[i-1];j++)
             if(abs(j-dig[i])>1) ans+=f[i][j];
          if(abs(dig[i]-dig[i-1])<=1) break;
       }
       return ans;
    }
    
    int main()
    {
       int dig,b;init();
       while(scanf("%d%d",&dig,&b)!=EOF)
       {
          int ans=solve(b+1)-solve(dig);
          printf("%d
    ",ans);
       }
       return 0;
    }
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int dp[25][25];
    int dig[25],len;
    int dfs(int pos,int pre,int z,int lim)
    {
        if(pos<=0) return 1;
        if(z&&!lim&&dp[pos][pre]!=-1) return dp[pos][pre];
        int num=lim?dig[pos]:9;
        int ans=0;
        if(z==0)
        {
            for(int i=0;i<=num;i++)
              ans+=dfs(pos-1,i,i,lim&&(i==num));
        }
        else
        {
            for(int i=0;i<=num;i++)
            {
                if((i-pre)*(i-pre)<4) continue;
                ans+=dfs(pos-1,i,1,lim&&(i==num));
            }
        }
        if(z&&!lim) dp[pos][pre]=ans;
        return ans;
    }
    int count(int x)
    {
        len=0;
        while(x)
        {
            dig[++len]=x%10;
            x/=10;
        }
        memset(dp,-1,sizeof(dp));
        return dfs(len,0,0,1);
    }
    int main()
    {
        int l,r;
        while(scanf("%d%d",&l,&r)!=-1)
        {
            printf("%d
    ",count(r)-count(l-1));
        }
        return 0;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    Codeforces Round 546 (Div. 2)
    Codeforces Round 545 (Div. 2)
    Codeforces Round 544(Div. 3)
    牛客小白月赛12
    Codeforces Round 261(Div. 2)
    Codeforces Round 260(Div. 2)
    Codeforces Round 259(Div. 2)
    Codeforces Round 258(Div. 2)
    Codeforces Round 257 (Div. 2)
    《A First Course in Probability》-chaper5-连续型随机变量-随机变量函数的分布
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7190924.html
Copyright © 2011-2022 走看看