题目链接: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. unittest 单元测试框架

    引入 unittest 框架 相想使用unittest 框架,首先要引入unittest 包 import unittest class Baidu(unittest.TestCase): Baidu ...

  2. LCD屏背光驱动调试心得---血的教训

    开发板:明远智睿MY-IMX6-EK140 内核源码:linux-3.14.52 背光驱动IC:MP3202 调光原理:通过开发板的核心板PWM4引脚控制MP3202的EN脚,输出不同的占空比从而达到 ...

  3. 【Axure插件】之浏览器打开失败

    下载地址:https://files.cnblogs.com/files/Owen-ET/AxureRP_for_chorme_0_6_2.xml 下载后的文件后缀修改为:AxureRP_for_ch ...

  4. java栈的最大深度?

    1. 概述 某公司面试,总监大叔过来,问了图论及栈的最大深度,然后^_^ 一直记着,今天搞一下 2. 代码 package com.goodfan.test; public class JavaSta ...

  5. 更改Mysql 密码的4种方法(转)

    原文:http://www.jb51.net/article/39454.htm 方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password f ...

  6. Cobbler部署之FAQ处理

    Cobbler报错处理 通过cobbler check检查出现的报错 红色标注为报错关键信息 9.1 报错一 # cobbler check httpd does not appear to be r ...

  7. 关于html的小bug

    废话不说 看代码 因为最近比较忙  所以不闲聊了啊 <!DOCTYPE html> <html lang="en"> <head> <me ...

  8. WebView 显示网页

    1.布局 <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:androi ...

  9. python设置环境变量

    方法1: 当程序开发完毕,就可以添加到 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages'中 ...

  10. phpStorm pycharm编辑器主题修改,自定义颜色

    新的启程 注: 本人小菜鸟一枚,内容也是从其他博客中借鉴的,谨以此作为写博客开端. phpstorm修改主题: 1. phpstorm主题下载 http://www.phpstorm-themes.c ...