RQNOJ-8 2^k进制数

题意:给定k和w,求r的个数,其中r作为2^k进制时至少要2位且每一位严格小于右边,r作为2进制时总位数不超过w。 (k<=9,w<=30000)

题解:若已知2^k进制下,最高位最大为a,总位数为b,则总数为,其中。这个公式的意思是最高位为i,再从中选取个数插入剩下的b-1个位置中。

排列可用递推预处理

ps.高精度

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
using namespace std;
const int N=513;
struct BigNum{
    int a[202],n;
}C[N][N];
BigNum operator +(BigNum u,BigNum v){
    BigNum w;memset(w.a,0,sizeof w.a);
    w.n=max(u.n,v.n);
    for (int i=1;i<=w.n;i++){
        w.a[i]+=u.a[i]+v.a[i];
        w.a[i+1]+=w.a[i]/10;
        w.a[i]%=10;
    }
    if (w.a[w.n+1])w.n++;
    return w;
}
void Print(BigNum u)
{
    if (u.n==0){puts("0");return ;}
    for (int i=u.n;i>=1;i--)printf("%d",u.a[i]);
}
int main()
{
    //freopen("1.txt","r",stdin);
    for (int i=0;i<N;i++){C[i][0].n=1;C[i][0].a[1]=1;}
    for (int i=1;i<N;i++)for (int j=1;j<=i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];
    int K,W,a;
    BigNum Sum;memset(Sum.a,0,sizeof Sum.a);Sum.n=1;
    cin>>K>>W;
    for (int b=2;b<=(W+K-1)/K;b++){
        int tmp=(b==(W+K-1)/K)?W%K:K;if (tmp==0)tmp=K;
        a=0;for (int i=0;i<tmp;i++)a=a*2+1;//
        for (int i=1;i<=a;i++){
            if ((1<<K)-1-i<b-1)break;
            Sum=Sum+C[(1<<K)-1-i][b-1];
        }
    }
    Print(Sum);
    return 0;
}



发布了74 篇原创文章 · 获赞 30 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/MustImproved/article/details/52557534