zoukankan      html  css  js  c++  java
  • 某关于数位DP的一节课后的感受

    题目 

    求给定区间[x,y]中满足下列条件的整数个数,这个数恰好等于k个互不相等的B的整数次幂之和

    Input

    15 20 2 2

    Out

    17 18 20

    示例:17=24+20 18=24+21 20=24+22

    为什么15和16不行呢??? 因为15=23+22+21+20 此时K>2明显不成立 而16=23+23

    此时B明显相等就无法通过 其实我们可以把它当成B进制的数来算(~~其实我也是听老师讲的~~)

    在这里我们把它化成一棵树 然后转化成0,1的格式,去寻找它的一的数量是否符合所要求的数

    Such As

    贼丑

    好丑,其实是闲着蛋疼画的【图不一定是对的只是为了看得明显一点......】

    这样就可以在树里寻找所满足条件的结果 为什么用0和1呢

    Because Of

    17=2^4+2^0

    18=2^4+2^1

    20=2^4+2^2

    这个实际上就是B进制数

    如下:

    17=1*2^4+0*2^3+0*2^2+1*2^1+0*2^0

    17=10001

    同理18=10010 20=10100 15=1111 16=10000

    所以说可以在树中找它的1的数量就可以找出答案

    //对f进行预处理(变得多多的。。。) 
    void init(){
        f[0][0]=1;
        for(int i=1;i<=31;i++){
            f[i][0]=f[i-1][0];
            for(int j=1;j<=i;j++)
                f[i][j]=f[i-1][j]+f[i-1][j-1];//状态转移方程
        }
    }

    为了给它放进树里所做的努力!!!

    然后去搜寻树中的1,一般情况下左子树的1要比右子树的一来得少

     当满足条件时就可以记录下来

    上面的例子中可以看出有两个1即可

    此时就可以存储。。。

    int cal(int x,int k){
        int tot,ans;//tot当前路径还有的1的个数 
        for(int i=31;i>0;i--){
            if(x&(1<<i)){
                tot++;
                if(tot>k)break;
                x=x^(1<<i);
            }
            if(1<<(i-1)<=x){
            ans+=f[i-1][k-tot];
            }
        }
        if((tot+x)==k) ans++;
        return x;
    }

    答案的输出

    cal(y,k)-cal(x-1,k) 

    这个答案的取值

    嗯......

    用上面做示范:

    就是:

    [1,20]--[1,14]=[15,20]

    基本没错啦

    (这个[x,y]是区间的意思)

    这样可以找到答案

    (如果有错敬请各位大佬指出)

    跪地求RP

  • 相关阅读:
    November 07th, 2017 Week 45th Tuesday
    November 06th, 2017 Week 45th Monday
    November 05th, 2017 Week 45th Sunday
    November 04th, 2017 Week 44th Saturday
    November 03rd, 2017 Week 44th Friday
    Asp.net core 学习笔记 ( Area and Feature folder structure 文件结构 )
    图片方向 image orientation Exif
    Asp.net core 学习笔记 ( Router 路由 )
    Asp.net core 学习笔记 ( Configuration 配置 )
    qrcode render 二维码扫描读取
  • 原文地址:https://www.cnblogs.com/U58223-luogu/p/9462382.html
Copyright © 2011-2022 走看看