喵哈哈村的狼人杀大战(5)
发布时间: 2017年3月7日 20:10 最后更新: 2017年3月7日 20:11 时间限制: 1000ms 内存限制: 128M
喵哈哈村最近热衷于玩一个叫做狼人杀的游戏!
沈宝宝同学今天他抽到的是狼人的身份,按照他的一贯玩法,他喜欢一开始就自爆,让大家都不能说话,可谓心狠手辣。
于是他早早的就出去了。
但是他现在很无聊,于是他出了一道题给自己玩。
如果一个数的二进制表示中有k个1的话,那么这个就是就是k-th数。
比如有10(1010)就是2-th数,8(100)就是1-th数。
现在给你一个n和一个R,让你确认这些n-th数,输出满足要求的n-th数的和,这些数得满足在区间[0,R)内。
本题包含若干组测试数据。
每组测试数据包含两个整数,n,R.
满足 0<=n<=1000,0<R<=2^1000
注意 R 的读入是以2进制的方式读入的。
输出数的和,答案需要对10^9+7取模
复制
1 1000
7
想到了答案=所有位的贡献(当前位为1的值*当前位为1时的所有合法方案数)之和,但不知道怎么求所有合法方案
数,于是只好用数位dp,最后还没写做出来......
题目链接:http://qscoj.cn/problem/34/
于是看了题解:http://www.cnblogs.com/qscqesze/p/6516139.html
/* http://qscoj.cn/problem/34/ */
#include<stdio.h>
#include<string.h>
#define mod 1000000007
#define LL long long
LL C[1005][1005], bit[1005] = {0,1};
char str[1005];
int main(void)
{
int i, j, n, len;
long long ans, sum;
for(i=2;i<=1001;i++)
bit[i] = (bit[i-1]*2)%mod;
for(i=0;i<=1001;i++)
C[i][0] = C[i][i] = 1;
for(i=2;i<=1001;i++)
{
for(j=1;j<=i-1;j++)
C[i][j] = (C[i-1][j]+C[i-1][j-1])%mod;
}
while(scanf("%d%s", &n, str+1)!=EOF)
{
ans = sum = 0;
len = strlen(str+1);
for(i=1;i<=len && n>=0;i++)
{
if(str[i]=='1' && len-i>=n)
{
ans = (ans+sum*C[len-i][n])%mod;
if(n>0)
ans = (ans+(bit[len-i+1]-1)*C[len-i-1][n-1])%mod;
sum = (sum+bit[len-i+1])%mod;
n -= 1;
}
}
printf("%lld\n", ans);
}
return 0;
}