BZOJ1044: [HAOI2008]木棍分割 (二分 + DP)
题意:n根木棍依次连在一起 最多切m个端点 使得最长的一段最小
在保证最长的最小的情况下 有多少种不同的切法
题解:第一问傻子都知道二分
第二问想了一会不会做 但其实就是很简单的dp
dp[i][j]表示切完第i刀切到第j段后面的的种数
想了一下觉得空间过不去 然而这个是可以滚动的 因为每一刀的转移都只和前一刀有关系 再优化下时间
预处理一下last[i]表示在第i个木棍后面切的话 至少要在last[i]这个点及以后也切一下
跃然纸上的转移 dp[i][j] += dp[i - 1][k] if(last[j] <= k < j) 但这是个接近n^3的复杂度
然后发现每次转移 dp[i][j]都是加的相同一段 所以我们可以每次前缀和搞一下
#include <bits/stdc++.h> using namespace std; const int mod = 10007;int n, m; int q[50005]; int sum[50005]; int last[50005]; int dp[2][50005]; int pre[2][50005]; int ans1, ans2;int check(int x) {int res = 0;int cnt = 0;for(int i = 1; i <= n; i++){res += q[i];if(res > x) cnt++, res = q[i];}return cnt; }int main() {ans2 = 0;scanf("%d%d", &n, &m);int l = 0, r = 0;for(int i = 1; i <= n; i++){scanf("%d", &q[i]);l = max(l, q[i]); r += q[i];}int mid = l + r >> 1;while(l + 1 < r){mid = l + r >> 1;if(check(mid) <= m) ans1 = mid, r = mid;else l = mid;}if(check(l) <= m) ans1 = l;int zsum = 0;int p = 1;for(int i = 1; i <= n; i++){zsum += q[i];while(zsum > ans1) zsum -= q[p], p++;last[i] = p - 1;if(last[i] == 0) dp[1][i] = 1;}ans2 += dp[1][n];for(int i = 1; i <= n; i++) pre[1][i] = (dp[1][i] + pre[1][i - 1]) % mod;for(int i = 2; i <= m + 1; i++){memset(dp[i & 1], 0, sizeof(dp[i & 1]));pre[i & 1][i - 1] = 0;for(int j = i; j <= n; j++){dp[i & 1][j] = (dp[i & 1][j] + pre[(i - 1) & 1][j - 1]) % mod;if(last[j]) dp[i & 1][j] = (dp[i & 1][j] - pre[(i - 1) & 1][last[j] - 1]) % mod;dp[i & 1][j] = (dp[i & 1][j] + mod) % mod;}for(int j = i; j <= n; j++) pre[i & 1][j] = (pre[i & 1][j - 1] + dp[i & 1][j]) % mod;ans2 = (ans2 + dp[i & 1][n]) % mod;}printf("%d %d\n", ans1, ans2);return 0; }
View Code
转载于:https://www.cnblogs.com/lwqq3/p/9774514.html
BZOJ1044: [HAOI2008]木棍分割 (二分 + DP)相关推荐
- 【bzoj1044】[HAOI2008]木棍分割 二分+dp
题目描述 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且 ...
- BZOJ1044: [HAOI2008]木棍分割(dp 单调队列)
题意 题目链接 Sol 比较套路的一个题. 第一问二分答案check一下 第二问设\(f[i][j]\)表示前\(i\)个数,切了\(j\)段的方案数,单调队列优化一下. 转移的时候只需要保证当前段的 ...
- bzoj 1044: [HAOI2008]木棍分割(二分+DP)
1044: [HAOI2008]木棍分割 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4363 Solved: 1686 [Submit][St ...
- haoi2008木棍分割解题报告
[问题描述] 有n根木棍,第i根木棍的长度为Li,n根木棍依次连结在一起,总共有n-1个连接处.现在允许你最多砍断m个连接处,砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小,并且输出有 ...
- 木棍分割[HAOI2008]
题目描述 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连 接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并 ...
- 2017.3.13 木棍分割 思考记录
肯定是二分+dp 但只能想出n^2m dp 感觉每个数字的状态都和前面的数字和有关,但划分是灵活的,可以衍生出多种前缀和的情况. 看了题解,但是: .. .一脸懵逼,,代码是还pascal的.. ...
- 【BZOJ1044】【tyvj3511】【codevs1870】木棍分割,二分答案+滚动数组+前缀和DP
传送门1 传送门2 传送门3 写在前面:就我看来,这是一道不错的题 思路: 一.对于"求总长度最大的一段的长度最小值"这个问题,我们比较容易想到二分答案然后判断是否合法,显然这个是 ...
- hdu1025 Constructing Roads In JGShining#39;s Kingdom(二分+dp)
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1025 Problem ...
- bzoj 1863 二分+dp check
思路:二分之后用dp去check就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se ...
最新文章
- sketch如何做设计稿交互_做交互设计不可不知的十大原则
- 为什么要使用main函数
- 一文读懂Faster R-CNN目标检测
- Windows核心编程 第26章 窗口消 息
- 【PP】生产发货仓位决定
- 【分享】java反射获取、设置、打印对象属性,对象转map基础工具
- 玩玩短视频平台和网课平台开发1——腾讯云对象储存COS的初步配置
- keil5——常见报错【cannot load flash device description】
- 信用评分-(scorecard)记分卡开发流程,详细介绍分数校准原理calibration
- 制作 maxdos 启动盘 Linux 安装盘
- 2016.8.14安装myplayer心得
- 基于ssm的空气质量监测系统
- 汽车营销与保险【3】
- Minecraft mod制作简易教程(五)——本地化和国际化
- Linux如何检查是否支持SNI,WDCP下的纯Nginx支持多域名ssl证书(TLS SNI support disabled)解决方案...
- ccna综合实验实训总结_CCNA实训总结
- 智能分析网关微信端告警消息推送的开发流程
- CSS中常用选择器总结
- Ubports安装和使用gedit和ros等记录(仅供参考)
- linux文件e属性,三、Linux文件属性
热门文章
- mysql opensuse_opensuse免安装mysql
- blob jdbc mysql,JDBC能否处理Blob和Clob?
- python创建sqlite3数据库_Python之Sqlite3数据库基本操作
- h3c交换机配置远程管理_高手给说下H3C交换机如何配置telnet远程登录
- matlab 二值化_撸了一份 ostu二值化,需要的小伙伴请拿走
- 计算机网络现在成功,百收计算机网络努力的人是怎么成功的
- bat/cmd 抛出错误码和捕获错误
- 激光振镜误差校正算法C语言,动态聚焦激光振镜扫描系统的误差分析及图形校正算法.pdf...
- 数据结构(二)--队列
- linux 64 内存管理,[内存管理]linux X86_64处理器的内存布局图