BIGSEQ - Sequence

You are given the sequence of all K-digit binary numbers: 0, 1,..., 2K-1. You need to fully partition the sequence into M chunks. Each chunk must be a consecutive subsequence of the original sequence. Let Si (1 ≤ i ≤ M) be the total number of 1's in all numbers in the ith chunk when written in binary, and let S be the maximum of all Si, i.e. the maximum number of 1's in any chunk. Your goal is to minimize S.

Input

In the first line of input, two numbers, K and M (1 ≤ K ≤ 100, 1 ≤ M ≤ 100, M ≤ 2^K), are given, separated by a single space character.

Output

In one line of the output, write the minimum S that can be obtained by some split. Write it without leading zeros. The result is not guaranteed to fit in a 64-bit integer.

Example

Input:
3 4 Output:
4
 
【题意】
  给定所有 K 位二进制数:0,1,…,2^K-1。你需要将它们分成恰好 M 组,每组都是原序列中连续的一些数。设 Si(1 ≤ i ≤ M)表示第 i 组中所有数的二进制表示中 1 的个数,S 等于所有 Si 中的最大值。你的任务是令 S 最小。 【分析】
  这题竟然1A了超级感动。
  人生第一道重载运算符的高精度。
  主要就是高精度真是好恶心哦..看着别人的代码打的,重载运算符之后就直接用了很方便。
  
   进入正题,最大值最小,我们就想到可以二分S,然后划分区间使得每个区间都小于S。
  问题就变成了有限制S,然后把它划分成最少的区间,判断区间数是否<=m。
  假设我们现在在st的位置,要找最远的ed使得st+1到ed中的数的1的个数<=S。
  设c[i]表示小于等于i的数的1的个数和,上面的限制就是c[ed]-c[st]<=S -> c[ed]<=S+c[st]
  所以变成找最大的ed使c[ed]<=S+c[st]。
  c数组当然不能每个都求,我们用到他的时候就用数位DP求,具体过程就是模拟填数。
  找最大的ed使c[ed]<=S+c[st]也是一个模拟填数的过程,也是一个数位DP。
 
  数位DP中用到的数组是d[i],f[i]。
d[i]表示2^i,f[i]表示小于等于d[i]的数中的1的个数和。初始化求出这两个数组。
  
  填数的时候注意1的个数计算。我一开始就傻逼了。
  前面填过的1并没有在答案中减去,判断可不可以走左子树的时候要记得把这个也加上判断。
代码如下:
 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
#include<cmath>
using namespace std;
#define Maxn 110 struct bign
{
int len,a[Maxn];
bign ()
{
memset(a,,sizeof(a));
len=;
}
bign (int num)
{
*this = num;
}
bign operator = (const int num)
{
char s[Maxn];
sprintf(s,"%d",num);
*this = s;
return *this;
}
bign operator = (const char *num)
{
while(num[]=='') num++;
len=strlen(num);
for(int i=;i<len;i++)
a[i]=num[len-i-]-'';
return *this;
}
bign operator + (const bign &b)
{
bign c;
c.len=;
for(int i=,g=;g||i<max(len,b.len);i++)
{
int x=g;
if(i<len) x+=a[i];
if(i<b.len) x+=b.a[i];
c.a[c.len++]=x%;
g=x/;
}
return c;
}
bign operator += (const bign &b)
{
*this=*this+b;
return *this;
}
void clean()
{
while(len> && !a[len-]) len--;
}
bign operator * (const bign &b)
{
bign c;
c.len=len+b.len;
for(int i=;i<len;i++)
for(int j=;j<b.len;j++)
c.a[i+j]+=a[i]*b.a[j];
for(int i=;i<c.len;i++)
{
c.a[i+]+=c.a[i]/;
c.a[i]%=;
}
c.clean();
return c;
}
bign operator *= (const bign &b)
{
*this=*this * b;
return *this;
}
bign operator - (const bign b)
{
bign c;
c.len=;
for(int i=,g=;i<len;i++)
{
int x=a[i]-g;
if(i<b.len) x-=b.a[i];
if(x>=) g=;
else
{
g=;
x+=;
}
c.a[c.len++]=x;
}
c.clean();
return c;
}
bign operator -= (const bign &b)
{
*this = *this -b;
return *this;
}
bign operator / (const int b)
{
bign c;
int f=;
for(int i=len-;i>=;i--)
{
f=f*+a[i];
c.a[i]=f/b;
f=f%b;
}
c.len=len;
c.clean();
return c;
}
bign operator / (const bign &b)
{
bign c,f=;
for(int i=len-;i>=;i--)
{
f=f*;
f.a[]=a[i];
while(f>=b)
{
f-=b;
c.a[i]++;
}
}
c.len=len;
c.clean();
return c;
}
bign operator /= (const bign &b)
{
*this = * this /b;
return * this;
}
bign operator % (const bign &b)
{
bign r= *this /b;
r=*this-r*b;
return r;
}
bign operator %= (const bign &b)
{
*this=*this%b;
return *this;
}
bool operator < (const bign &b)
{
if(len!=b.len) return len<b.len;
for(int i=len-;i>=;i--)
if(a[i]!=b.a[i]) return a[i]<b.a[i];
return false;
}
bool operator > (const bign &b)
{
if(len!=b.len) return len>b.len;
for(int i=len-;i>=;i--)
if(a[i]!=b.a[i]) return a[i]>b.a[i];
return false;
}
bool operator == (const bign &b)
{
return !(*this>b) && !(*this<b);
}
bool operator != (const bign &b)
{
return !(*this==b);
}
bool operator <= (const bign &b)
{
return (*this<b)||(*this==b);
}
bool operator >= (const bign &b)
{
return (*this>b)||(*this==b);
}
}; void output(bign x)
{
for(int i=x.len-;i>=;i--) printf("%c",x.a[i]+'');
printf("\n");
} int k,m;
bign d[Maxn],f[Maxn];
void init()
{
d[]=;
for(int i=;i<=k;i++) d[i]=d[i-]*;
f[]=;
for(int i=;i<=k;i++) f[i]=f[i-]*+d[i-];
} bign get_ct(bign x)
{
bign ans=;
if(x==-) return ;
int y=;
for(int i=k;i>=;i--)
{
bign now=x/d[i-];
if(now==) ans+=f[i-]+d[i-]*y,y++;
x%=d[i-];
}
return ans+y;
} bign get_f(bign x)
{
bign ans=;
int y=;
for(int i=k;i>=;i--)
{
if(d[i-]*y+f[i-]<x) ans+=d[i-],x-=d[i-]*y+f[i-],y++;
}
if(x>=y) return ans;
return ans-;
} bool check(bign x)
{
bign st=;
int now=;
while(st<d[k]-)
{
bign y=get_ct(st),ed=get_f(y+x);
now++;
if(now>m) return ;
st=ed;
}
return ;
} void ffind()
{
bign l=,r=f[k];
while(l<r)
{
bign mid=(l+r)/;
if(check(mid)) r=mid;
else l=mid+;
}
output(l);
} int main()
{
scanf("%d%d",&k,&m);
init();
ffind();
return ;
}

[SPOJ 2319]


 

打这个真是太不容易了!!!!


放一个大神的题解,如果看不懂我说的东西的话:

 
												

【SPOJ 2319】 BIGSEQ - Sequence (数位DP+高精度)的更多相关文章

  1. spoj 2319 BIGSEQ - Sequence

    You are given the sequence of all K-digit binary numbers: 0, 1,..., 2K-1. You need to fully partitio ...

  2. 【SPOJ】2319 BIGSEQ - Sequence

    [算法]数位DP [题解]动态规划 题目要求的是大整数……没办法只写了小数字的,感觉应该没错. 大题框架是最大值最小化的二分问题. 对于每一块要求count(b)-count(a-1)≥s 已知a如何 ...

  3. bzoj 1223: [HNOI2002]Kathy函数 数位DP 高精度

    1223: [HNOI2002]Kathy函数 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 207  Solved: 90[Submit][Stat ...

  4. SPOJ BALNUM - Balanced Numbers - [数位DP][状态压缩]

    题目链接:http://www.spoj.com/problems/BALNUM/en/ Time limit: 0.123s Source limit: 50000B Memory limit: 1 ...

  5. spoj 10606 Balanced Numbers 数位dp

    题目链接 一个数称为平衡数, 满足他各个数位里面的数, 奇数出现偶数次, 偶数出现奇数次, 求一个范围内的平衡数个数. 用三进制压缩, 一个数没有出现用0表示, 出现奇数次用1表示, 出现偶数次用2表 ...

  6. HDU 2062 Subset sequence 数位dp,思路 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=2062 Subset sequence Time Limit: 1000/1000 MS (Java/Others ...

  7. [spoj1182][Sorted Bit Sequence] (数位dp)

    Description Let's consider the 32 bit representation of all integers i from m up to n inclusive (m ≤ ...

  8. 【专题】数位DP

    [资料] ★记忆化搜索:数位dp总结 之 从入门到模板 by wust_wenhao 论文:浅谈数位类统计问题 数位计数问题解法研究 [记忆化搜索] 数位:数字从低位到高位依次为0~len-1. 高位 ...

  9. 【SPOJ 1182】 SORTBIT - Sorted bit squence (数位DP)

    SORTBIT - Sorted bit squence no tags Let's consider the 32 bit representation of all integers i from ...

随机推荐

  1. HTTP请求、响应报文格式

    HTTP请求报文格式: HTTP请求报文主要由请求行.请求头部.空行以及请求正文4部分组成 1,请求行由3部分组成,分别为:请求方式,URI(注意这里不是URL)以及协议版本组成,之间由空格分隔 请求 ...

  2. java Spring配置数据单元

    基本原理 - 容器和bean 在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean. 简单地讲,bean就是由Spring容器初始化 ...

  3. C#&JQuery非缓存式无刷新临时存储数据之仿购物车功能

    感谢广大博问博友的帮助和共同研究讨论,终于实现了一个无缓存无刷新仿购物车的小功能: 一.实现效果简述: 有一种列表,是由双层Repeater嵌套,第一层用来显示类别,第二层用来显示类别下的商品数据, ...

  4. Spring 和 MyBatis 环境整合

    本案例主要是讲述Spring  和  MyBatis 的环境整合 , 对页面功能的实现并没有做的很完整 先附上本案例的结构 1 . 创建项目并导入相关jar包 commons-collections4 ...

  5. [python]pep8编码规范

    一 代码编排1 缩进.4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格.2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号.换行点要在操作符的后边敲回车.3 类 ...

  6. Js编码和Java后台解码

    1.java.将resultMsg 转为utf-8 (1) resultMsg = URLEncoder.encode(resultMsg, "utf-8"); (2) new S ...

  7. 对REST的一些理解

    昨天学习REST,发现有篇文章写的真心不错,看了一遍,并没有完全理解,将一些感觉比较重要的做个记录.  文章链接:REST简介 定义 Representational State Transfer ( ...

  8. 无责任共享 Coursera、Udacity 等课程视频

    本文转载自网络,原作者不详. (本文是用 markdown 写的,访问 https://www.zybuluo.com/illuz/note/71868 获得更佳体验) 程序语言 interactiv ...

  9. 最近使用Qt遇到的一些小问题解决办法总结

    1. 我想获取当前星期几这样的,我没在API里面找到这样的函数,但是我找到了今天是第几天这样的,所以自己转换一下就OK了: typedef struct { int numInWeek; QStrin ...

  10. C++类继承内存布局(三)

    参考:http://blog.csdn.net/jiangyi711/article/details/4890889# (三)成员函数 类X中每一个非静态成员函数都会接受一个特殊的隐藏参数——this ...