zoukankan      html  css  js  c++  java
  • 2k进制数

    2k进制数

    设r是个2k进制数,并满足以下条件:
    (1)r至少是个2位的2k进制数。
    (2)作为2k进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位。
    (3)将r转换为2进制数q后,则q的总位数不超过w。
    在这里,正整数k(1≤k≤9)和w(k< W< span>≤30000)是事先给定的。
    问:满足上述条件的不同的r共有多少个?
    我们再从另一角度作些解释:设S是长度为w 的01字符串(即字符串S由w个“0”或“1”组成),S对应于上述条件(3)中的q。将S从右起划分为若干个长度为k 的段,每段对应一位2k进制的数,如果S至少可分成2段,则S所对应的二进制数又可以转换为上述的2k进制数r。
    例:设k=3,w=7。则r是个八进制数(23=8)。由于w=7,长度为7的01字符串按3位一段分,可分为3段(即1,3,3,左边第一段只有一个二进制位),则满足条件的八进制数有:
    2位数:高位为1:6个(即12,13,14,15,16,17),高位为2:5个,…,高位为6:1个(即67)。共6+5+…+1=21个。
    3位数:高位只能是1,第2位为2:5个(即123,124,125,126,127),第2位为3:4个,…,第2位为6:1个(即167)。共5+4+…+1=15个。
    所以,满足要求的r共有36个。
    输入描述:
    只有1行,为两个正整数,用一个空格隔开:
    k W
    输出描述:
    共1行,是一个正整数,为所求的计算结果,即满足条件的不同的r的个数(用十进制数表示),要求最高位不得为0,各数字之间不得插入数字以外的其他字符(例如空格、换行符、逗号等)。
    (提示:作为结果的正整数可能很大,但不会超过200位)
    样例输入:
    3 7
    样例输出:
    36
    思路:
    这个2k进制数最多能有s=(w+k)/k位,且最高位的值不超过m=2wmodk-1。(当w可整除k时,虽然s多算了一位,但此时最高位的最大值m的值为0,不影响正确答案)
    这就是条件1和条件3的含义。
    就剩条件2了,它本质上是告诉我们递推关系。有两种思路:
    第一种,用f(i,j)代表长度为i且最右边一位不超过j的数的个数,则有f(i,j)=f(i,j-1)+f(i-1,j-1),即f(i,j)=最右边一位不是j的方案数f(i,j-1)加上最右边一位是j的方案数f(i-1,j-1)
    答案ans=Σs-1i=2f[i][2k-1]+Σmi=1f[s-1][n-i]。
    相当于长度小于s的最高位不超过2k?1的数的个数加上长度等于s的最高位不超过m的数的个数。
    这里f[s-1][n-i]的意思是长为s的数已确定最高位为i,还剩s-1位。这些位的数字可以是(i+1,i+2,…,n),共n?i个数,所以长为s-1,最左边为i+1而最右边不超过n的数的个数与最左边为1而最右边为n?i的数的个数相同,为f[s-1][n-i]。

    #include<iostream>
    using namespace std;
    unsigned long long k,w,m,s,n;
    struct node
    {
        int l;
        int a[50];
    }f[580][520],ans;
    void add(node &x,node &y)
    {
        int lena=x.l,lenb=y.l,lenc=1,tmp=0;
        int c[1001]={0};
        while(lenc<=lena||lenc<=lenb)
        {
            c[lenc]=x.a[lenc]+y.a[lenc]+tmp;
            tmp=c[lenc]/10;
            c[lenc]%=10;
            lenc++;
        }
        c[lenc]=tmp;
        while(lenc>1&&c[lenc]==0)
        lenc--;
        x.l=lenc;
        for(int i=1;i<=lenc;i++)
        x.a[i]=c[i];
    }
    int main()
    {
        cin>>k>>w;
        s=(k+w)/k;
        m=(1<<(w%k))-1;
        n=(1<<k)-1;
        for(int i=1;i<=n;i++)
        {
            int tmp=i;
            while(tmp)
            {
                f[1][i].l++;
                f[1][i].a[f[1][i].l]=tmp%10;
                tmp/=10;
            }
        }
        for(int i=2;i<=s;i++)
          for(int j=i;j<=n;j++)
          add(f[i][j],f[i-1][j-1]),
          add(f[i][j],f[i][j-1]);
        for(int i=2;i<s;i++)
        add(ans,f[i][n]);
        for(int i=1;i<=m;i++)
        add(ans,f[s-1][n-i]);
        for(int i=ans.l;i>=1;i--)
        cout<<ans.a[i];
        return 0;
    }
  • 相关阅读:
    use paramiko to connect remote server and execute command
    protect golang source code
    adjust jedi vim to python2 and python3
    install vim plugin local file offline
    add swap file if you only have 1G RAM
    datatables hyperlink in td
    django rest framework custom json format
    【JAVA基础】网络编程
    【JAVA基础】多线程
    【JAVA基础】String类的概述和使用
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070984.html
Copyright © 2011-2022 走看看