【动态规划】bzoj1044: [HAOI2008]木棍分割
需要滚动优化或者short int卡空间
Description
有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连
接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少种砍的方法使得总长
度最大的一段长度最小. 并将结果mod 10007。。。
Input
输入文件第一行有2个数n,m.接下来n行每行一个正整数Li,表示第i根木棍的长度.n<=50000,0<=m<=min(n-1,10
00),1<=Li<=1000.
Output
输出有2个数, 第一个数是总长度最大的一段的长度最小值, 第二个数是有多少种砍的方法使得满足条件.
Sample Input
1
1
10
Sample Output
HINT
两种砍的方法: (1)(1)(10)和(1 1)(10)
题目分析
昨天做到这道题的稍微强化版:允许空集存在。我那题想法是,强制没有空集,最后再用组合数统计答案。状态$f[i][j]$表示前$i$个数分为$j$个非空集合的方案数,$t[i]$表示最小能够与$i$合并的位置。于是$f[i][j]=\sum_{x=t[i]}^{i}{f[i][j-1]}$。这里有一个$\sum_{i}{f[i][j]}$的形式,自然用前缀和优化。
组合数溢出调了好久……
#include<bits/stdc++.h>
const int maxn = ;
const int MO = ; int n,m,mxBound,mnBound,ans;
int a[maxn],s[maxn],t[maxn],g[maxn][maxn];
int f[maxn][maxn];
int C[maxn][maxn]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
bool check(int x)
{
int cnt = , sum = ;
for (int i=; i<=n; i++)
if (sum+a[i] > x) sum = a[i], cnt++;
else sum += a[i];
return cnt <= m;
}
int qmi(int a, int b)
{
int ret = ;
while (b)
{
if (b&) ret = 1ll*ret*a%MO;
a = 1ll*a*a%MO, b >>= ;
}
return ret;
}
int main()
{
// freopen("ex_t2.in","r",stdin);
n = read(), m = read(), C[][] = ;
for (int i=; i<=m; i++)
{
C[i][] = ;
for (int j=; j<=i; j++)
C[i][j] = (C[i-][j]+C[i-][j-])%MO;
}
for (int i=; i<=n; i++)
a[i] = read(), mxBound += a[i], mnBound = mnBound < a[i]?a[i]:mnBound, s[i] = s[i-]+a[i];
int l = mnBound, r = mxBound, head = , tot = ;
for (int mid=(l+r)>>; l<=r; mid=(l+r)>>)
if (check(mid)) ans = mid, r = mid-;
else l = mid+;
printf("%d\n",ans);
for (int i=; i<=n; i++)
{
tot += a[i];
while (tot > ans) tot -= a[head++];
t[i] = head;
}
g[][] = f[][] = , ans = ;
for (int i=; i<=n; i++)
{
g[i][] = ;
for (int j=; j<=m; j++)
{
int delta = g[i-][j-];
if (t[i]>) delta -= g[t[i]-][j-];
(f[i][j] += 1ll*delta+MO) %= MO;
(g[i][j] = 1ll*g[i-][j]+1ll*f[i][j]) %= MO;
}
}
for (int i=; i<=m; i++)
ans = (ans+1ll*C[m][i]*f[n][i])%MO;
printf("%d\n",ans);
return ;
}
但是强化版空间512M,这题却只有162M。
首当其冲想到滚动数组优化,不过由于在这题里滚动数组需要把$j$放在枚举的外层,因此在一些奇怪的原因影响下效率会变得非常低。
注意到本题的模数非常小(不知道是不是出题人的善意),于是可以把$f[i][j]$开成short int省去一半空间。
再注意到其实同时开$f[i][j]$与$g[i][j]$是没有必要的,我们完全可以把$f[i][j]$表示成$g[i][j]$的前缀和形式,从而又省去一半空间。
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ;
const int MO = ; int n,m,mxBound,mnBound,ans;
int a[maxn],s[maxn],t[maxn];
short int g[maxn][maxm]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
bool check(int x)
{
int cnt = , sum = ;
for (int i=; i<=n; i++)
if (sum+a[i] > x) sum = a[i], cnt++;
else sum += a[i];
return cnt <= m;
}
int main()
{
// freopen("1044.in","r",stdin);
// freopen("1044.out","w",stdout);
n = read(), m = read()+;
for (int i=; i<=n; i++)
a[i] = read(), mxBound += a[i], mnBound = mnBound < a[i]?a[i]:mnBound, s[i] = s[i-]+a[i];
int l = mnBound, r = mxBound, head = , tot = ;
for (int mid=(l+r)>>; l<=r; mid=(l+r)>>)
if (check(mid)) ans = mid, r = mid-;
else l = mid+;
printf("%d ",ans);
for (int i=; i<=n; i++)
{
tot += a[i];
while (tot > ans) tot -= a[head++];
t[i] = head;
}
register int i,j;
ans = ;
for (i=; i<=n; i++) g[i][] = ;
for (int i=; i<=n; i++)
{
for (int j=; j<=m; j++)
{
int delta = g[i-][j-];
if (t[i]>) delta -= g[t[i]-][j-];
(g[i][j] = g[i-][j]+delta) %= MO;
}
}
for (i=; i<=m; i++)
ans = (ans+g[n][i]-g[n-][i]+MO)%MO;
printf("%d\n",ans);
return ;
}
END
【动态规划】bzoj1044: [HAOI2008]木棍分割的更多相关文章
- BZOJ1044: [HAOI2008]木棍分割
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1580 Solved: 567[Submit][Statu ...
- bzoj1044[HAOI2008]木棍分割 单调队列优化dp
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4314 Solved: 1664[Submit][Stat ...
- BZOJ1044 [HAOI2008]木棍分割 【二分+Dp】
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4281 Solved: 1644 [Submit][St ...
- [BZOJ1044][HAOI2008]木棍分割 二分+贪心+dp+前缀和优化
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4112 Solved: 1577 [Submit][St ...
- 【czy系列赛】czy的后宫6 && bzoj1044 [HAOI2008]木棍分割
题目描述 众所周知的是丧尸czy有很多妹子(虽然很多但是质量不容乐观QAQ),今天czy把n个妹子排成一行来检阅.但是czy的妹子的质量实在--所以czy看不下去了.检阅了第i个妹子会增加czy a[ ...
- [bzoj1044][HAOI2008][木棍分割] (二分+贪心+dp+队列优化)
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- bzoj1044: [HAOI2008]木棍分割 二分+dp
有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少 ...
- BZOJ1044: [HAOI2008]木棍分割(dp 单调队列)
题意 题目链接 Sol 比较套路的一个题. 第一问二分答案check一下 第二问设\(f[i][j]\)表示前\(i\)个数,切了\(j\)段的方案数,单调队列优化一下. 转移的时候只需要保证当前段的 ...
随机推荐
- 阿里巴巴开源性能监控神器Arthas初体验
如果问性能测试中最难的是哪部分,相信很多人会说“性能调优”.确实是这样,性能调优是一个非常复杂.技术含量很高的工作.涉及到的知识面很广.以我多年从业经验来看,在企业里,大多数的性能调优都是由开发架构师 ...
- 1-28Map简介
Map接口概述 除了Collection之外,常用的集合还有Map接口,里面常用的实现类图如下: map中的元素是以键-值的方式存在的,通过键可以获取到值,键是不可以重复的,跟地图比较像,通过一个坐标 ...
- Hibernate-Session使用的背后
一.Session缓存的介绍 简单说,缓存介于应用程序和数据库之间,是临时存放数据的内存区域,作用是减少对数据库的访问次数,从而提高应用程序的运行性能.Session有一个缓存,也叫hibernate ...
- 最耗资源的10条sql
----当前最耗资源的10个cpu select * from (select address,hash_value, round(cpu_time/1000000) cpu_time_s, roun ...
- SpringBoot项目取消数据库配置
1. 错误springboot项目启动时,如果没有配置数据库配置,启动时会抛出如下异常. Description: Cannot determine embedded database driver ...
- IIS网站设置禁止IP访问设置方法
本文设置系统为Windows2003.IIS版本是6.0. 打开IIS管理器,在iis管理器左侧单击打开网站下面的相应需要设置的网站,并在此网站上右键,选择属性,即可打开该网站属性进行相关设置. (i ...
- nodejs 快要变成爬虫界的王者
nodejs 快要变成爬虫界的王者 爬虫这东西是很多数据采集必须要的东西. 但是现在随着网页不断发展,已经出现了出单纯的网页,到 ajax 网页, 再到 spa , 再到 websocket 应用,一 ...
- I/O————字符流和流的关闭
Reader字符输入流 Writer字符输出流 用于字符的形式读取和写入数据 FileReader与FileWriter分别是Reader与Writer的子类 public class CharScr ...
- leetcode134 Gas Station
思路: https://leetcode.com/problems/gas-station/discuss/269604/Java-Greedy-thought-process 关键是要想清楚如果从加 ...
- 一个简单的注册页面,基于JS
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...