Discription

The Travelling Salesman spends a lot of time travelling so he tends to get bored. To pass time, he likes to perform operations on numbers. One such operation is to take a positive integer x and reduce it to the number of bits set to 1 in the binary representation of x. For example for number 13 it's true that 1310 = 11012, so it has 3 bits set and 13 will be reduced to 3 in one operation.

He calls a number special if the minimum number of operations to reduce it to 1 is k.

He wants to find out how many special numbers exist which are not greater than n. Please help the Travelling Salesman, as he is about to reach his destination!

Since the answer can be large, output it modulo 109 + 7.

Input

The first line contains integer n (1 ≤ n < 21000).

The second line contains integer k (0 ≤ k ≤ 1000).

Note that n is given in its binary representation without any leading zeros.

Output

Output a single integer — the number of special numbers not greater than n, modulo 109 + 7.

Example

Input
110
2
Output
3
Input
111111011
2
Output
169

Note

In the first sample, the three special numbers are 3, 5 and 6. They get reduced to 2 in one operation (since there are two set bits in each of 3, 5 and 6) and then to 1 in one more operation (since there is only one set bit in 2).

最简单的数位dp类型,多加一维0\1表示是否贴上界(当初自己想的方法没想到还挺靠谱,,,基本上用了的题都对了)。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#define ll long long
#define maxn 1010
#define ha 1000000007
using namespace std;
char s[maxn];
int n,m,c[maxn];
int num[maxn],k,ans;
int f[maxn][maxn][2];
//f[i][j][0/1]表示前i位中和为j,且是否贴上界的方案数 inline int add(int x,int y){
x+=y;
if(x>=ha) x-=ha;
return x;
} inline void init(){
num[0]=0;
for(int i=1;i<=1005;i++) num[i]=num[i^(i&-i)]+1;
c[1]=0,c[0]=123456;
for(int i=2;i<=1005;i++){
c[i]=c[num[i]]+1;
//c[i]<5,虽然可能并没有什么卵用
}
} inline void solve(){
n=strlen(s+1);
//一开始是贴上界的,因为之前的位都是0。
f[0][0][1]=1;
for(int i=1;i<=n;i++) if(s[i]=='1'){
//这一位是1的话是不可能选的数1个数为0且贴上界
f[i][0][0]=add(f[i-1][0][0],f[i-1][0][1]);
f[i][0][1]=0;
for(int j=1;j<=i;j++){
//不贴上界可能是 这一位为0且之前是否贴上界任意 或者 这一位为1且之前不贴上界
f[i][j][0]=add(add(f[i-1][j][0],f[i-1][j][1]),f[i-1][j-1][0]);
//贴上界只能是之前贴上界且当前位是1
f[i][j][1]=f[i-1][j-1][1];
}
}
else{
f[i][0][0]=f[i-1][0][0];
f[i][0][1]=f[i-1][0][1];
for(int j=1;j<=i;j++){
//不贴上界的话只能 这一位为0且之前不贴上界 或者 这一位为1且之前不贴上界
f[i][j][0]=add(f[i-1][j][0],f[i-1][j-1][0]);
//之所以没有f[i-1][j-1][1]是因为这一位是1的话是不可能贴上界的
f[i][j][1]=f[i-1][j][1];
}
} ans=0;
for(int i=0;i<=n;i++) if(c[i]==k-1) ans=add(ans,add(f[n][i][0],f[n][i][1])); //这样枚举<=n的数的1的个数会有一个漏洞,那就是1将会被算到k==1的里面去,所以要特判一下
if(k==0) ans++;
else if(k==1) ans--;
} int main(){
init();
scanf("%s",s+1);
scanf("%d",&k);
solve();
printf("%d\n",ans);
return 0;
}

  

Codeforces 914 C Travelling Salesman and Special Numbers的更多相关文章

  1. Codeforces 914 C. Travelling Salesman and Special Numbers (数位DP)

    题目链接:Travelling Salesman and Special Numbers 题意: 给出一个二进制数n,每次操作可以将这个数变为其二进制数位上所有1的和(3->2 ; 7-> ...

  2. Codeforces 374 C. Travelling Salesman and Special Numbers (dfs、记忆化搜索)

    题目链接:Travelling Salesman and Special Numbers 题意: 给了一个n×m的图,图里面有'N','I','M','A'四种字符.问图中能构成NIMA这种序列最大个 ...

  3. Codeforces 914C Travelling Salesman and Special Numbers:数位dp

    题目链接:http://codeforces.com/problemset/problem/914/C 题意: 对数字x进行一次操作,可以将数字x变为x在二进制下1的个数. 显然,一个正整数在进行了若 ...

  4. Travelling Salesman and Special Numbers CodeForces - 914C (数位dp)

    大意: 对于一个数$x$, 每次操作可将$x$变为$x$二进制中1的个数 定义经过k次操作变为1的数为好数, 求$[1,n]$中有多少个好数 注意到n二进制位最大1000位, 经过一次操作后一定变为1 ...

  5. Codeforces 914C Travelling Salesman and Special Numbers (数位DP)

    题意:题目中定义了一种运算,把数字x变成数字x的二进制位数.问小于n的恰好k次运算可以变成1的数的个数(题目中的n是二进制数,n最大到2^1000) 思路:容易发现,无论多么大的数,只要进行了一次运算 ...

  6. 【Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) C】 Travelling Salesman and Special Numbers

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 会发现. 进行一次操作过后. 得到的数字肯定是<=1000的 然后1000以下可以暴力做的. 则我们枚举第1步后得到的数字x是 ...

  7. HDU 5402(Travelling Salesman Problem-构造矩阵对角最长不相交路径)

    Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (J ...

  8. HDU 5402 Travelling Salesman Problem (构造)(好题)

    大致题意:n*m的非负数矩阵,从(1,1) 仅仅能向四面走,一直走到(n,m)为终点.路径的权就是数的和.输出一条权值最大的路径方案 思路:因为这是非负数,要是有负数就是神题了,要是n,m中有一个是奇 ...

  9. HDOJ 5402 Travelling Salesman Problem 模拟

    行数或列数为奇数就能够所有走完. 行数和列数都是偶数,能够选择空出一个(x+y)为奇数的点. 假设要空出一个(x+y)为偶数的点,则必须空出其它(x+y)为奇数的点 Travelling Salesm ...

随机推荐

  1. POJ1847:Tram(最短路)

    Tram Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 20116   Accepted: 7491 题目链接:http:/ ...

  2. Codeforces Round #520 (Div. 2) A. A Prank

    A. A Prank time limit per test   1 second memory limit per test    256 megabytes 题目链接:https://codefo ...

  3. Linux下只允许用户远程scp

    本文将介绍在Linux环境下,让用户不能远程登录 只能使用scp命令 使用到的软件:rssh(http://pizzashack.org/rssh/index.shtml ) 环境:centos6.x ...

  4. Javascript 的addEventListener()及attachEvent()区别分析

    大家都知道事件的用法就是当某个事件(状况)被触发了之后就会去执行某个Function, 尤其是Javascript, 在当红AJAX的催化下, 了解Javascript的Event用法更加重要, 在这 ...

  5. 动态规划:划分DP

    划分型动态规划之数的划分 先贴上2014年10月31日的那份代码,甚至怀念当时在机房YY这道题的场面 高中最快乐的时候.. #include<iostream> using namespa ...

  6. karma和jasmine的测试(包括angular测试)

    本篇博客主要就是针对现在日新月异的技术和快速开发,测试被很多人忽略,其实在开发中如何保证代码的质量以及逻辑的完整性,测试显得十分重要,本文就是负责karma+jasmine来测试. 1.搭建测试的环境 ...

  7. [vue-router] Failed to resolve async component default: Error: Loading chunk 0 failed.

    在整合laravel5.4 和vue2.1的时候遇到一个奇怪的问题 Uncaught SyntaxError: Unexpected token < Error: Loading chunk 0 ...

  8. LCD实验学习笔记(一):Makefile

    主Makefile总领全局的就这句—— lcd.bin: $(objs) 要生成lcd.bin,依赖于objs列举的一堆文件:head.o init.o nand.o interrupt.o seri ...

  9. (转)linux samb服务器配置

    1. 首先安装samba服务. 2. 配置防火墙(要先关闭) 3. 创建samba服务器用户:smbpasswd -a username     删除samba服务器用户:smbpasswd -x u ...

  10. rtp/rtsp over http的学习

    要做rtp/rtsp over http, 我对http也有点了解, 以前也做过rtp/rtsp over tcp/udp传输264视频流, 但刚开始还是没有一点思路,想着把http和rtp等联系到一 ...