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;
    }
  • 相关阅读:
    springIOC 原理
    jeesite异步分页
    yum
    乐观锁原理
    equlas(),hashcode(),hashset,hashmap
    链接收藏
    java单词
    jeesite优化
    SailingEase .NET Resources Tool (.NET 多语言资源编辑器)转
    C#基本语法
  • 原文地址:https://www.cnblogs.com/five20/p/9651489.html
Copyright © 2011-2022 走看看