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

    题目描述

    r是个2k 进制数,并满足以下条件:

    (1)r至少是个2位的2k 进制数。

    (2)作为2k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位。

    (3)将r转换为2进制数q后,则q的总位数不超过w

    在这里,正整数k(1≤k≤9)w(k<W≤30000)是事先给定的。

    问:满足上述条件的不同的r共有多少个?

    我们再从另一角度作些解释:设S是长度为w 的01字符串(即字符串Sw个“0”或“1”组成),S对应于上述条件(3)中的q。将S从右起划分为若干个长度为k的段,每段对应一位2k进制的数,如果S至少可分成2段,则S所对应的二进制数又可以转换为上述的2k进制数r

    例:设k=3,w=7。则r是个八进制数(23=8)。由于w=7,长度为701字符串按3位一段分,可分为3段(即1,3,3,左边第一段只有一个二进制位),则满足条件的八进制数有:

    2位数:
    高位为16个(即12,13,14,15,16,17),
    高位为2:5个,
    …,
    高位为6:1个(即67)。
    6+5+…+1=216+5+…+1=216+5++1=21个。

    3位数:
    高位只能是1
    2位为25个(即123,124,125,126,127),
    2位为3:4个,
    …,
    2位为61个(即167)。
    5+4+…+1=15个。

    所以,满足要求的r共有36个。

    输入输出格式

    输入格式:

    2个正整数,用一个空格隔开:

    kW

    输出格式:

    1个正整数,为所求的计算结果,即满足条件的不同的r的个数(用十进制数表示),要求最高位不得为0,各数字之间不得插入数字以外的其他字符(例如空格、换行符、逗号等)。

    (提示:作为结果的正整数可能很大,但不会超过200位)

    输入输出样例

    输入样例#1: 
    3 7
    输出样例#1: 
    36

    说明

    NOIP 2006 提高组 第四题

    Solution:

      本题DP+高精。

      DP比较明显,定义状态$f[i][j]$表示第$i$位为$j$的方案数,则$f[i][j]=sum f[i-1][k],k<j$。

      首先第一维是可以滚掉的,然后转移时不需要枚举$k$,我们直接改下状态$f[i][j]$表示第$i$位$leq j$的方案数,每次转移时改为维护前缀和,就能做到$O(w)$转移($frac{w}{k} imes k=w$)。

      那么再在DP的基础上写个高精就好了。

    代码:

    /*Code by 520 -- 9.14*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    const int N=55,Base=1e5;
    int n,m;
    struct node{
        int a[N],len;
        il void Clr(){memset(a,0,sizeof a),len=0;}
        il void Push(int x){a[len=1]=1;}
        node operator + (const node &x) const{
            node tp;tp.Clr();tp.len=max(len,x.len)+5;
            For(i,1,tp.len)
                tp.a[i]+=a[i]+x.a[i],
                tp.a[i+1]+=tp.a[i]/Base,
                tp.a[i]%=Base;
            For(i,1,tp.len) tp.a[i+1]+=tp.a[i]/Base,tp.a[i]%=Base;
            while(tp.len&&!tp.a[tp.len]) tp.len--;
            return tp;
        }
        il void Output(){
            printf("%d",a[len]);
            Bor(i,1,len-1) printf("%05d",a[i]);
        }
    }ans,f[2][520];
    
    int main(){
        cin>>n>>m;
        int pos=m/n,rest=m%n;
        int minn=(1<<rest)-1,maxn=(1<<n)-1;
        if(!rest) minn=maxn,pos--;
        Bor(i,1,maxn) f[0][i].Push(1);
        Bor(i,1,maxn) f[0][i]=f[0][i]+f[0][i+1];
        int tag=0;
        For(i,1,pos-1){
             Bor(j,1,maxn) f[tag^1][j]=f[tag^1][j]+f[tag^1][j+1]+f[tag][j+1],f[tag][j+1].Clr();
             f[tag][1].Clr();
             tag^=1,ans=ans+f[tag][1];
        }
        Bor(j,1,minn) f[tag^1][j]=f[tag^1][j]+f[tag^1][j+1]+f[tag][j+1];
        ans=ans+f[tag^1][1];
        ans.Output();
        return 0;
    }
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/five20/p/9651489.html
Copyright © 2011-2022 走看看