zoukankan      html  css  js  c++  java
  • hdu 5787 K-wolf Number 数位dp

    K-wolf Number

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5787

    Description

    Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation of x is pairwised different.
    Given (L,R,K), please count how many K-wolf numbers in range of [L,R].

    Input

    The input contains multiple test cases. There are about 10 test cases.

    Each test case contains three integers L, R and K.

    1≤L≤R≤1e18
    2≤K≤5

    Output

    For each test case output a line contains an integer.

    Sample Input

    1 1 2
    20 100 5

    Sample Output

    1
    72

    Hint

    题意

    问你[L,R]里面有多少个数,其中相同的数字至少相差k位。

    题解:

    显然的数位dp,我们记录前k-1个数是哪些就好了。

    空间要滚动一下。

    代码

    #include <bits/stdc++.h>
    #define rep(a,b,c) for(int (a)=(b);(a)<=(c);++(a))
    #define drep(a,b,c) for(int (a)=(b);(a)>=(c);--(a))
    #define pb push_back
    #define mp make_pair
    #define sf scanf
    #define pf printf
    #define two(x) (1<<(x))
    #define clr(x,y) memset((x),(y),sizeof((x)))
    #define dbg(x) cout << #x << "=" << x << endl;
    #define lowbit(x) ((x)&(-x))
    const int mod = 1e9 + 7;
    int mul(int x,int y){return 1LL*x*y%mod;}
    int qpow(int x , int y){int res=1;while(y){if(y&1) res=mul(res,x) ; y>>=1 ; x=mul(x,x);} return res;}
    inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
    using namespace std;
    const int maxn = 200 + 15;
    char str[maxn];
    int len , bit[ 100500 ] , K , ten[10] ;
    vector < int > number[ 100050 ];
    long long dp[2][2][2][6][ 10050 ];
    
    inline void up(long long & x , long long v){ x += v; }
    
    void init(){
        number[0].pb( 0 );
        ten[0] = bit[0] = 1;
        for(int i = 1 ; i < 8 ; ++ i) ten[i] = ten[i - 1] * 10;
        for(int i = 1 ; i <= 10000 ; ++ i){
            int x = i;
            while( x > 0 ){
                number[i].pb( x % 10 );
                bit[i] |= ( 1 << ( number[i].back() ) );
                x /= 10;
            }
            reverse( number[i].begin() , number[i].end() );
        }
    }
    
    pair < int , int > Transform( int st , int l , int add ){
        int rs = st * 10 + add;
        if( l < K ) return mp( rs , l + 1 );
        else{
            if( rs >= ten[K] ) return mp( rs - ten[K] * number[st][0] , K ) ;
            else return mp( rs , K );
        }
    }
    
    long long solve( long long x ){
        if( x == 0 ) return 1LL;
        len = 0;
        while( x > 0 ){
            str[ ++ len ] = (x % 10) + '0';
            x /= 10;
        }
        reverse( str + 1 , str + len + 1 );
        int cur = 0;
        clr( dp[cur] , 0 );
    
        // 第 i 位 , 下界标志 f1 , 前导零标记 f2 , 状态 st 的位数 , 状态 st
    
        dp[cur][0][1][0][0] = 1;
        for(int i = 1 ; i <= len ; ++ i){
            int pre = cur ; cur ^= 1;
            clr( dp[cur] , 0 );
            for(int f1 = 0 ; f1 < 2 ; ++ f1)
                for(int f2 = 0 ; f2 < 2 ; ++ f2)
                    for(int l = 0 ; l <= K ; ++ l)
                        for(int st = 0 ; st < 10000 ; ++ st)
                            if( dp[pre][f1][f2][l][st] ){
                                int ed = f1 ? 9 : str[i] - '0';
                                for(int add = 0 ; add <= ed ; ++ add){
                                    int newf1 = f1 | ( add < ed );
                                    int newf2;
                                    if( f2 == 0 ) newf2 = 0;
                                    else{
                                        if( add == 0 ) newf2 = 1;
                                        else newf2 = 0;
                                    }
                                    if( ((bit[st] >> add) & 1)==1 && f2 ==0 ) continue;
                                    if( number[st].size() < l && add == 0 ) continue; // 有前导 0 
                                    if( f2 == 1 && add == 0 ) up( dp[ cur ][ newf1 ][ 1 ][ 0 ][ 0 ] , dp[pre][f1][f2][l][st] );
                                    else{
                                        pair < int , int > rp = Transform( st , l , add );
                                        up( dp[ cur ][ newf1 ][ 0 ][ rp.second ][ rp.first ] , dp[pre][f1][f2][l][st] );
                                    }
                                }
                            }
        }
        long long ans = 0;
        for(int f1 = 0 ; f1 < 2 ; ++ f1) for(int f2 = 0 ; f2 < 2 ; ++ f2) for(int l = 0 ; l <= K;  ++ l) for(int st = 0 ; st < 10000 ; ++ st) up( ans , dp[cur][f1][f2][l][st] );
        return ans;
    }
    
    int main(int argc,char *argv[]){
        init();
        long long L , R ;
        while(~sf("%I64d%I64d%d",&L,&R,&K)){
            -- K;
            pf("%I64d
    " , solve( R ) - solve( L - 1 )) ;
        }
        return 0;
    }
  • 相关阅读:
    子查询
    主键、外键
    语句、聚合函数、数学函数、字符串函数、时间日期函数
    数据库的备份、还原、分离、附加
    SQL server数据类型、增删改查
    轮播特效
    手风琴特效
    关于Winform中的用户代理
    详细的SQL中datediff用法
    sql server 的datediff函数
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5730394.html
Copyright © 2011-2022 走看看