zoukankan      html  css  js  c++  java
  • HDU 5787 K-wolf Number(数位DP)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5787

     

    【题目大意】

      求区间【L,R】内十进制数相邻k位之间不相同的数字的个数。

    【题解】

       很显然的数位dp,但是状态不知道该怎么转移,然后发现了递归数位DP这种神奇的姿势,每次记录前k位的数字,然后枚举下一位能用的数字,递归即可。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring> 
    using namespace std;
    typedef long long ll;
    const int N=25,M=10005;
    int bit[N],pw[5],k;
    ll dp[N][M][2][2],l,r;
    ll DP(int d,int x,bool f,bool lim){
        int c[5];
        if(d==-1)return 1;
        ll &ret=dp[d][x][f][lim];
        if(~ret)return ret; ret=0;
        int st=k-1,y=x,pos=0;
        for(int i=0;i<k;i++)c[i]=y%10,y/=10;
        if(!f){while(!c[st]&&st>=0)st--;}
        for(int i=st;i>=0;i--)pos|=1<<c[i];
        int up=lim?bit[d]:9;
        for(int i=0;i<=up;i++){
            if(pos>>i&1)continue;
            if(f)ret+=DP(d-1,(x-pw[k-1]*c[k-1])*10+i,f,lim&&i==up);
            else if(st==-1&&!i)ret+=DP(d-1,0,0,lim&&i==up);
            else ret+=DP(d-1,x*10+i,st==k-2,lim&&i==up);
        }return ret;
    }
    ll Cal(ll x){
        if(!x)return 1;int cnt=0;
        while(x)bit[cnt++]=x%10,x/=10;
        memset(dp,-1,sizeof(dp));
        return DP(cnt-1,0,0,1);
    }
    int main(){
        for(int i=pw[0]=1;i<5;i++)pw[i]=pw[i-1]*10;
        while(~scanf("%lld%lld%d",&l,&r,&k)){
            k--;printf("%lld
    ",Cal(r)-Cal(l-1));
        }return 0;
    }
    

      

  • 相关阅读:
    mysql数据库存放路径
    mysql 5.5安装不对容易出现问题
    bean的scope属性
    spring四种依赖注入方式
    spring依赖注入(反转控制)
    Tomcat 安装错误
    synchronized详解
    git tag命令
    vjson.hpp
    cmake添加版本号
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu5787.html
Copyright © 2011-2022 走看看