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;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    973. K Closest Points to Origin
    919. Complete Binary Tree Inserter
    993. Cousins in Binary Tree
    20. Valid Parentheses
    141. Linked List Cycle
    912. Sort an Array
    各种排序方法总结
    509. Fibonacci Number
    374. Guess Number Higher or Lower
    238. Product of Array Except Self java solutions
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7190924.html
Copyright © 2011-2022 走看看