小飞飞


私信TA

用户名:xiaofeifei

访问量:3419

签 名:

等  级
排  名 29964
经  验 509
参赛次数 0
文章发表 4
年  龄 0
在职情况 学生
学  校 西华大学
专  业

  自我简介:

解题思路:

  题目的例子为例,长度为7位的01字串按3位一段就这样分:0 000 000。其中除了首段,每段都小于(111)2,也即小于2k,而首段自然是小于2w%k(对于w%k为0时也成立)了。

    如果首段为0,则当这个2k进制数位数分别为2、3、…、[n/k]时,如果用b_max表示2k,对应的解的个数分别为C[b_max-1][2]、C[b_max-1][3]、…、C[b_max-1][n/k](C[i][j]表示从i个数里选j个构成一组组合)。

    如果首段不为0,设首段为x,则解就有c[b_max-x-1][n/k]个。

    这样,求解的个数就搞定了,剩下的活就是高精了。求组合数可以用这个公式:C[n][m]=C[n-1][m-1]+C[n-1][m],这样高精就只用加法了。


注意事项:





参考代码:

#include<cstdio>  

#include<algorithm>  

#include<iostream>

#define maxn1 200  

#define maxn2 1000  

using namespace std;


int ans[maxn1 + 20];

int f[maxn2 + 100][maxn1 + 20];


void add(int a[], int b[])

{

int i, j, k, last = 0;

a[0] = max(a[0], b[0]);

for (i = 1; i <= a[0]; i++)

{

a[i] += b[i] + last;

last = a[i] / 10, a[i] %= 10;

}

if (last>0)a[++a[0]] = last;

}


int main()

{

int i, j, k, x, y, w;

cin >> k >> w;

if (w <= k) { 

cout << "0" << endl; 

return 0;

}


y = (1 << k) - 1;

if (w%k == 0)x = y, k = w / k - 1;

else x = (1 << (w%k)) - 1, k = w / k;


f[1][0] = 1, f[1][1] = 1;

ans[0] = 0;


for (i = 1; i <= y; i++)

{

for (j = i + 1; j >= 1; j--)

add(f[j], f[j - 1]);

if (i >= y - x && i<y)add(ans, f[k + 1]);

}

for (i = 3; i <= k + 1; i++)

add(ans, f[i]);

for (i = ans[0]; i >= 1; i--)

cout << ans[i];

cout << endl;

return 0;

}


 

0.0分

0 人评分

  评论区

  • «
  • »