题目链接:http://codeforces.com/problemset/problem/914/C

题意:

  对数字x进行一次操作,可以将数字x变为x在二进制下1的个数。

  显然,一个正整数在进行了若干次操作后一定会变成1。

  给定n,k(n用二进制表示给出,n <= 2^1000)。

  问你有多少不超过n的正整数,将它们变为1所需的操作次数恰好为k。

题解:

  由于n <= 2^1000,所以任何不超过n的数在进行了一次操作后,一定不超过1000。

  所以先统计出1000以内所有数变成1所需的操作次数:f[i] = f[cal_bit(i)] + 1

  那么最终答案 = ∑(恰好包含i个1,且不超过n的数字个数),其中f[i] == k-1。

  所以接下来就要求恰好包含i个1,且不超过n的数字个数:

    表示状态:

      dp[i][j][0/1]表示已经填了前i位数,用了j个1,是否与n匹配(0/1),此时的方案数。

      (n的最高位为第1位)

    找出答案:

      恰好包含i个1,且不超过n的数字个数 = dp[n][i][0] + dp[n][i][1]

    如何转移:

      对于dp[i][j][0]:

        dp[i+1][j][0] += dp[i][j][0]

        dp[i+1][j+1][0] += dp[i][j][0]

      对于dp[i][j][1]:

        如果n的第i+1位为1:

          dp[i+1][j][0] += dp[i][j][1]

          dp[i+1][j+1][1] += dp[i][j][1]

        否则:

          dp[i+1][j][1] += dp[i][j][1]

    边界条件:

      dp[1][0][0] = dp[1][1][1] = 1

    最后统计下答案就好。

    其中k==0或1的情况要特判。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 1005
#define MOD 1000000007 using namespace std; int n,k;
int ans=;
int a[MAX_N];
int f[MAX_N];
int dp[MAX_N][MAX_N][];
string s; void read()
{
cin>>s>>k;
n=s.size();
for(int i=;i<n;i++) a[i+]=s[i]-'';
} int cal_bit(int x)
{
int cnt=;
int lowbit=x&-x;
while(lowbit)
{
cnt++;
x^=lowbit;
lowbit=x&-x;
}
return cnt;
} void cal_f()
{
f[]=;
for(int i=;i<=;i++)
{
f[i]=f[cal_bit(i)]+;
}
} void cal_dp()
{
memset(dp,,sizeof(dp));
dp[][][]=dp[][][]=;
for(int i=;i<n;i++)
{
for(int j=;j<=i;j++)
{
if(dp[i][j][])
{
dp[i+][j][]+=dp[i][j][];
dp[i+][j+][]+=dp[i][j][];
dp[i+][j][]%=MOD;
dp[i+][j+][]%=MOD;
}
if(dp[i][j][])
{
if(a[i+])
{
dp[i+][j][]+=dp[i][j][];
dp[i+][j+][]+=dp[i][j][];
dp[i+][j][]%=MOD;
dp[i+][j+][]%=MOD;
}
else
{
dp[i+][j][]+=dp[i][j][];
dp[i+][j][]%=MOD;
}
}
}
}
} void cal_ans()
{
for(int i=;i<=;i++)
{
if(f[i]==k-)
{
ans+=dp[n][i][]+dp[n][i][];
ans%=MOD;
}
}
} void work()
{
if(k==)
{
cout<<<<endl;
return;
}
cal_f();
cal_dp();
cal_ans();
if(k==) cout<<ans-<<endl;
else cout<<ans<<endl;
} int main()
{
read();
work();
}

Codeforces 914C Travelling Salesman and Special Numbers:数位dp的更多相关文章

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

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

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

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

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

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

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

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

  5. Codeforces 914 C Travelling Salesman and Special Numbers

    Discription The Travelling Salesman spends a lot of time travelling so he tends to get bored. To pas ...

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

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

  7. Codeforces Beta Round #51 D. Beautiful numbers 数位dp

    D. Beautiful numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/55/p ...

  8. 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP)

    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP) 链接:https://ac.nowcoder.com/acm/contest/163/ ...

  9. codeforces 55D - Beautiful numbers(数位DP+离散化)

    D. Beautiful numbers time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. Swing实现系统托盘

    /* 实现系统托盘化 */ protected void setToolSystemTray() { // 系统是否支持系统托盘 if (SystemTray.isSupported()) { // ...

  2. 小白学习HTTPS

    如果你和我一样是HTTPS的小白的话,那就一起来学习这个吧.争取把这篇博客写好,写全面,从原理到实践再到部署. 让我们先来模拟一个场景:当你嗨皮地敲着代码,你的老板偷偷摸摸跑到你的身边,"小 ...

  3. MHA常用命令

    .查看ssh登陆是否成功 masterha_check_ssh --conf=/etc/masterha/app1.cnf .查看复制是否建立好 masterha_check_repl --conf= ...

  4. WPF编程学习——样式(好文)

    http://www.cnblogs.com/libaoheng/archive/2011/11/20/2255963.html

  5. Unity Editor Inspector编辑模板

    效果图: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEdito ...

  6. iOS 递归锁

    原理:递归锁也是通过 pthread_mutex_lock 函数来实现,在函数内部会判断锁的类型.NSRecursiveLock 与 NSLock 的区别在于内部封装的 pthread_mutex_t ...

  7. thrift实例

    Thrift实例 Apache thrift是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架. 它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生 ...

  8. WPF 支持集合绑定的控件

    WPF 支持集合绑定的控件 ListBox ComboBox ListView DataGrid

  9. POJ 1694 An Old Stone Game【递归+排序】

    链接: http://poj.org/problem?id=1694 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27454#probl ...

  10. H5动静分离

    1. 动静分离的实现思路(类似于iOS.安卓的思路,后台提供数据接口,前端用ajax异步请求json数据,再把json数据渲染到页面) 动静分离是将网站静态资源(HTML,JavaScript,CSS ...