prologue

模拟赛的一道题,结果没做出来,丢大人,败大兴。所以过来糊一篇题解。

analysis

我们看到数据范围这么大,那么肯定不可以一个一个遍历(废话),所以就要考虑这个题目的性质。

我们先假设,极端数据 \(2 ^ {1000} - 1\),这个数字中包含了 \(999\) 个 1(正好感冒了能不能让我喝了)。下一次的数据就是 \(999\),这个时候,\(999\) 的二进制表示为 \(11 1110 0111\),下次就是 \(8\),再下次就是 \(1\) 了。这个时候的最少变换次数是 \(3\)。

我们看到这个数据缩小是很快的。那我们再进一步研究观察。

由于上限原因,所以我们第一次变换之后的数字一定为 \(\le 1000\) 的数字。我们又知道(不知道的掏计算器) \(2 ^ {10} = 1024\) 已经大于 1000 了,为了方便统计,适当放大数据。下次需要进行操作的数字就变成了 $ [0, 10] $ 就更小了,这个时候手搓一下,发现 \(7\) 这个数据是 \([0, 10]\) 之间的二进制表示下包含 1 最多的一个数字。

我们就求出来了这个恰好变换次数的上限。对于 100% 的数据而言,一定有:

  1. \(2 \le k \le 5\) 有解。
  2. \(k > 5\) 无解。

这个时候特判两个情况:

  1. \(k = 1\) 时,答案的个数为 \(length_s - 1\)。
  2. \(k = 0\) 时,答案为 1(只有 1 这种情况)。

我们之后就去考虑怎么计算这个值。

我们可以考虑一种类似于数位 dp 的思想,从高位往低位,用 \(f[i][j]\) 表示已经填了 i 个 1,剩下 j 位随便填,并且恰好 k 次变换之后能够变成 1 的方案数。

考虑递推式,从定义出发,预处理出来可能的值:

\[f[i][j] \gets f[i - 1][j]
\]
\[f[i][j] \gets f[i][j] + f[i - 1][j + 1], (j \le n - 1)
\]

计算方案数量:

\[res \gets (res + f[n - i - 1][t ++ ]) % P
\]

注意,如果我们最后的这个数字符合我们的最后变换数量少一,就是最后可以变到 1,我们要给方案数加 1。

code time

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rl register ll
#define endl '\n' const ll N = 1010, P = 1e9 + 7; char ch[N]; ll n, m, g[N], f[N][N]; int main()
{
scanf("%s%lld", ch, &m); n = strlen(ch); if(m == 0) puts("1");
else if(m == 1) cout << n - 1 << endl;
else if(m > 5) cout << "0" << endl;
else
{
for(rl i=2; i <= 1000; ++ i)
{
ll cnt = 0;
for(rl j=i; j; j >>= 1)
if(j & 1) cnt ++; g[i] = g[cnt] + 1;
} for(rl i=1; i <= n; ++ i) f[0][i] = g[i] == m - 1;
for(rl i=1; i <= n; ++ i)
for(rl j=0; j <= n; ++ j)
{
f[i][j] = f[i - 1][j];
if(j + 1 <= n) f[i][j] = (f[i][j] + f[i-1][j + 1]) % P;
} ll res = 0, t = 0;
for(rl i=0; i < n; ++ i)
if(ch[i] == '1')
{
res = (res + f[n - i - 1][t]) % P; t ++ ;
} if(g[t] == m - 1) cout << res + 1 << endl;
else cout << res << endl;
}
return 0;
}

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 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 ...

  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. Codeforces 914C Travelling Salesman and Special Numbers:数位dp

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

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

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

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

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

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

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

  10. HDOJ 5402 Travelling Salesman Problem 模拟

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

随机推荐

  1. 快速取模算法(Barrett Reduction)

    原理:取模运算低效的原因本质是除法运算的低效.如果能将除法变成其它运算就可以加速.具体地,将除以任意数转化成"乘一个数.除以一个 \(2^k\) "(取 \(2^{62}\) 即可 ...

  2. Dlang 并行化

    Dlang 并行化 好难受,dlang 生态太差,没办法,学了半天才明白. 我尽量以精炼的语言解释. 采用 定义,例子(代码),解释 的步骤讲解. 所以你可能看到很多代码,一点解释-- 我会省略一些 ...

  3. Java 设计模式实战系列—工厂模式

    在 Java 开发中,对象的创建是一个常见的场景,如果对象的创建和使用都写在一起,代码的耦合度高,也不利于后期的维护.我们可以使用工厂模式来解决这个问题,工厂模式是一个创建型模式,将对象的创建和使用分 ...

  4. MySQL 中分区表

    MySQL 中的分区表 InnoDB 逻辑存储结构 表空间 (Tablespace) 段 (segment) 区 (extent) 页 (page) 行 (row) InnoDB 数据页结构 分区别表 ...

  5. axios详解以及完整封装方法

    """ 一.axios是什么 Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中. 它是 isomorphic 的(即同一套代码可以运行 ...

  6. chrome事件循环的自问自答

    chrome事件循环的自问自答 目录 1. 宏任务有哪些? 2. 微任务有哪些? 3. dom渲染是事件循环的一部分么? 4. requestAnimationFrame的回调是宏任务还是微任务? 5 ...

  7. hdfs小文件合并

    HDFS small file merge 1.hive Settings There are 3 settings that should be configured before archivin ...

  8. FAQ: ansible playbook 中 tasks 与 handlers 的区别

    ansible自动化运维有两种执行方式,一种是对远程主机批量执行命令,使用ansible命令,直接调用模块加参数执行:另一种是对远程主机批量执行脚本,也是调用模块,但是要把参数按照yanl语法写到一个 ...

  9. opencv中的函数

    读入图像:cv2.imread(),第一个参数:未文件路径,第二个参数:告诉函数要以何种方式读取图片. cv2.IMREAD_COLOR:读入一幅彩色图像.图像的透明度会被忽略. cv2.IMREAD ...

  10. 【go语言】2.4.3 Go Modules

    Go Modules 是 Go 语言的官方依赖管理工具,自 Go 1.11 版本开始引入.它解决了 Go 语言在依赖管理上的一些问题,如版本控制.依赖隔离等. 初始化一个新的模块 你可以使用 go m ...