Problem

给定一个字符串数的二进制表示(不含前导0)s(长度不超过5000),

对于一个数n(初值为0),可以进行以下两种操作:

1.将n的二进制表示(无前导0)写到已经写的串的后面.

2.n加上1.

问组成s的不同方法数以及最少用多少次操作能组成串s.

Solution

对于第一问:

用f[i][j]表示最后一个数是j+1到i的方案数,g[i][j]表示操作1的个数

所以f[i][j]+=f[j][k](k < j < i 且 k到j的数小于j到i的数) ,因为如果k到j的位数比j到i的位数少,则k到j的数必定小于j到i的数

所以可以用前缀和优化,再在位数相等时特判一下

对于第二问:

我们可以知道,如果第二个操作的次数都大于总位数了,那么便是没有意义的

所以在有数的情况下,我们只要枚举后16位的转移,这是不会爆int的

但如果后16位的转移没法转移(不能有前导0),那么我们需要找到最后一个可以转移的地方来转移

那么所有的操作数就是最后的那个数加上操作1的个数

Notice

判断大小要用O(1),先预处理一下

Code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define sqz main
#define ll long long
#define reg register int
#define rep(i, a, b) for (reg i = a; i <= b; i++)
#define per(i, a, b) for (reg i = a; i >= b; i--)
#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)
const int INF = 1e9, mo = 1e9 + 7, N = 5005;
const double eps = 1e-6, phi = acos(-1.0);
ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}
ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}
void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}
int f[N][N], g[N][N], f_sum[N][N], g_min[N][N], T[N], S[N], mi[N], Same[N][N];
char st[N];
int cmp(int b1, int b2, int len)
{
int t = Same[b1][b2];
if (t >= len) return 1;
return T[b1 + t] < T[b2 + t];
}
int sqz()
{
scanf("%s", st + 1);
int n = strlen(st + 1);
rep(i, 1, n) T[i] = st[i] - '0';
mi[0] = 1;
rep(i, 1, n)
{
S[i] = (S[i - 1] * 2 + T[i]) % mo;
mi[i] = mi[i - 1] * 2 % mo;
}
per(i, n, 1)
per(j, n, 1)
if (T[i] == T[j]) Same[i][j] = Same[i + 1][j + 1] + 1;
else Same[i][j] = 0;
rep(i, 1, n)
{
f[i][0] = f_sum[i][0] = g[i][0] = g_min[i][0] = 1;
rep(j, 1, i - 1)
{
g[i][j] = g_min[i][j] = INF;
if (T[j + 1] == 1)
{
int k = j - (i - j);
if (k < -1) k = -1;
f[i][j] = (f[i][j] + f_sum[j][k + 1]) % mo;
g[i][j] = min(g[i][j], g_min[j][k + 1] + 1) % mo;
if (k + 1 && T[k + 1] && cmp(k + 1, j + 1, i - j))
{
f[i][j] = (f[i][j] + f[j][k]) % mo;
g[i][j] = min(g[i][j], g[j][k] + 1) % mo;
}
f_sum[i][j] = (f_sum[i][j] + f[i][j]) % mo;
g_min[i][j] = min(g_min[i][j], g[i][j]);
}
}
g_min[i][i] = INF;
per(j, i - 1, 0)
{
f_sum[i][j] = (f_sum[i][j] + f_sum[i][j + 1])% mo;
g_min[i][j] = min(g_min[i][j], g_min[i][j + 1]);
}
}
int ans = INF;
rep(i, 1, min(16, n)) ans = min(ans, g[n][n - i] + (int)((S[n] - (ll)S[n - i] * mi[i]) % mo + mo) % mo) % mo;
if (ans == INF)
rep(i, 17, n)
if (g[n][n - i] != INF)
{
ans = g[n][n - i] + (int)((S[n] - (ll)S[n - i] * mi[i]) % mo + mo) % mo;
break;
}
printf("%d\n%d\n", f_sum[n][0], ans);
}

[Codeforces477D]Dreamoon and Binary的更多相关文章

  1. Codeforces Round #272 (Div. 1)D(字符串DP)

    D. Dreamoon and Binary time limit per test 2 seconds memory limit per test 512 megabytes input stand ...

  2. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  3. ILJMALL project过程中遇到Fragment嵌套问题:IllegalArgumentException: Binary XML file line #23: Duplicate id

    出现场景:当点击"分类"再返回"首页"时,发生error退出   BUG描述:Caused by: java.lang.IllegalArgumentExcep ...

  4. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

  5. Leetcode 笔记 99 - Recover Binary Search Tree

    题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...

  6. Leetcode 笔记 98 - Validate Binary Search Tree

    题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...

  7. Leetcode: Convert sorted list to binary search tree (No. 109)

    Sept. 22, 2015 学一道算法题, 经常回顾一下. 第二次重温, 决定增加一些图片, 帮助自己记忆. 在网上找他人的资料, 不如自己动手. 把从底向上树的算法搞通俗一些. 先做一个例子: 9 ...

  8. Leetcode, construct binary tree from inorder and post order traversal

    Sept. 13, 2015 Spent more than a few hours to work on the leetcode problem, and my favorite blogs ab ...

  9. [LeetCode] Binary Watch 二进制表

    A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom ...

随机推荐

  1. JAVA:IDEA安装、创建项目、tomcat配置、maven配置(1)

    一.安装 JDK安装自行百度,IDEA安装: IDEA安装包下载:https://www.jetbrains.com/idea/download/ 安装过程一路默认,需要选择的就勾选 .java之类的 ...

  2. Javascript根据id获取数组对象

    在业务中,列表页跳转详情页时,经常会将Id值传入,然后再根据id值异步获取数据. 假设有服务端的json数据:  <注意,这里的data是指已经从后端获取的json, 而非后端原始的文件> ...

  3. 使用Navicat定时备份mysql数据库和创建报表并邮件自动发送

    数据库备份在现代计算机高速发展的今日变得日益重要,程序员往往因为不重视而忽略备份数据,导致数据丢失,造成非常严重的后果.定时备份无疑是解决备份的最好的途径,本文主要使用Navicat来自动备份数据库和 ...

  4. hive sql执行的job在map时报java.lang.OutOfMemoryError的错误

    较为详细且重要的一段报错信息是org.apache.hadoop.mapred.YarnChild: Error running child : java.lang.OutOfMemoryError: ...

  5. Jmeter对jar包的调用赋值

    一.前言 在我们测试接口的过程中,可能有时需要用到第三方jar包来生成一些测试数据(如有时需要对参数的输入值使用第三方jar包进行加密操作),涉及到这种的情况,普遍做法是:手动调用jar包获得需要的值 ...

  6. IntelliJ Idea 使用笔记

    1. IntelliJ Idea解决Could not autowire. No beans of 'xxxx' type found的错误提示. 原因可能有两个,第一个是IntellijIDEA本身 ...

  7. 微信公众号开发流程,jssdk的使用以及签名算法的实现

    一 开发流程 1 基本配置-登录自己的公众号 A:新型微信认证,认证过的企业号才可以进行自定义菜单中的连接跳转: B:开发基本配置里面进行开发者iD查询,密码查询和重置和ip白名单配置: C:公众号设 ...

  8. nginx-高并发配置 第七章

    一 .nginx 服务配置优化: 1.nginx进程数,建议按照cpu数目来指定,一般为它的倍数.worker_processes 定义了nginx对外提供web服务时的worker进程数.最优值取决 ...

  9. TCP之种种连接异常

    1. connect出错: (1) 若TCP客户端没有收到syn分节的响应,则返回ETIMEOUT错误:调用connect函数时,内核发送一个syn,若无响应则等待6s后再发送一个,若仍然无响应则等待 ...

  10. 基础的基于QT的图像查看程序

    代码来自<QT5.9c++开发指南>,因为实现了图片的遍历显示,对于将来编写ImageShop一类的图像程序来说将非常有用(这个程序目前存在一定问题,在研究过程中进行解决) 一.基本功能 ...