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. 20151221jquery学习笔记--验证插件

    验证插件(validate.js),是一款验证常规表单数据合法性的插件.使用它,极大的解放了在表单上繁杂的验证过程,并且错误提示显示的完善也增加了用户体验.一. 使用 validate.js 插件官网 ...

  2. lucene 4.4 demo

    ackage com.zxf.demo; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStr ...

  3. Ztree使用

    基础: <link rel="stylesheet" href="../../../css/zTreeStyle/zTreeStyle.css" type ...

  4. 巧谈 GCD

    转载自:http://www.jianshu.com/p/665261814e24 谈到iOS多线程,一般都会谈到四种方式:pthread.NSThread.GCD和NSOperation.其中,苹果 ...

  5. DBHelper 数据库帮助类

    /// <summary> /// 数据库帮助类 /// <author>vito</author> /// </summary> public cla ...

  6. java web-----DAO设计模式(数据库访问)

    一,DAO设计模式用于 j2ee 的数据层访问,包括五部分, 数据库连接类(包含数据库的连接与关闭操作的一个类), VO类(私有变量与数据库表格对应,接收数据库中表格各字段内容), DAO接口类(包含 ...

  7. 02_Jquery_03_类选择器

    [简述] 类选择器就是通过类名(css类名)来查询元素! $(".myClass")就可以把所有包含了class="myClass"的元素查询出来 [index ...

  8. avconv转换视频

    提取指定stream time avconv -i i.mkv -map 0:0 -map 0:1 -map 0:5 -c:v copy -c:a:0 mp3 -c:s copy o.mkv 合并 a ...

  9. 【转】使用PHP创建基本的爬虫程序

    Web Crawler, 也时也称scrapers,即网络爬虫,用于自动搜索internet并从中提取 想要的内容.互联网的发展离不开它们.爬虫是搜索引擎的核心,通过智能算法发现符合 你输入的关键字的 ...

  10. 【Android】 Sqlite3 not found

    调试机没有sqlite3命令文件 导入即可 sqlite3 http://pan.baidu.com/s/1bohTMiz //(使用老版sqlite3需要导入libncurses.so文件至/sys ...