第一问可以二分答案,然后贪心来判断.

第二问dp, dp[i][j] = sigma(dp[k][j - 1]) (1 <= k <i, sum[i] - sum[k] <= ans) dp[i][j] 表示前i根木棍切了j次最大长度<=ans的方案数。sum[i]为1~i 的木棍长度和(前缀和).明显可以用滚动数组优化.然后又会发现, 对于每个dp[i][j]求和过程中,sum[i]不变,而sum[k]是单调递增,满足的k值是一连续的区间,且满足的最小k随i变大而变大,所以可以用一个变量累计.复杂度O(nm).

-------------------------------------------------------------------------------------------------

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
 
#define rep(i, n) for(int i = 0; i < n; ++i)
#define Rep(i, l, r) for(int i = l; i <= n; ++i)
#define clr(x, c) memset(x, c, sizeof(x))
#define mod(x) ((x + 10007) %= 10007)
 
using namespace std;
 
const int maxn = 50000 + 5;
 
int n, m, ans = 0;
int sumL[maxn];
int d[maxn][2];
 
void Read() {
scanf("%d%d", &n, &m);
int t;
sumL[0] = 0;
Rep(i, 1, n) {
scanf("%d", &t);
sumL[i] = sumL[i - 1] + t;
}
}
 
bool jud(int ans) {
int cnt = m, front = 0, rear = 0;
while(rear < n) {
while(rear < n && sumL[rear + 1] - sumL[front] <= ans) rear++;
if(rear < n) {
front = rear;
if(--cnt < 0) return false;
}
}
return true;
}
 
void BS() {
int l = 0, r = sumL[n];
while(l <= r) {
int mid = (l + r) >> 1;
if(jud(mid)) { ans = mid; r = mid - 1; }
else l = mid + 1;
}
printf("%d ", ans);
}
 
void DP() {
int cur = 0, Ans = 0;
Rep(i, 1, n) d[i][cur] = sumL[i] <= ans ? 1 : 0;
d[0][0] = d[0][1] = 0;
while(m--) {
cur ^= 1;
int p = 0, sum = 0;
Rep(i, 1, n) {
while(sumL[i] - sumL[p] > ans) mod(sum -= d[p++][cur ^ 1]);
mod(d[i][cur] = sum);
mod(sum += d[i][cur ^ 1]);
}
mod(Ans += d[n][cur]);
}
printf("%d\n", Ans);
}
 
int main() {
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
Read();
BS();
DP();
return 0;
}

-------------------------------------------------------------------------------------------------

1044: [HAOI2008]木棍分割

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2095  Solved: 761
[Submit][Status][Discuss]

Description

有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少种砍的方法使得总长度最大的一段长度最小. 并将结果mod 10007。。。

Input

输入文件第一行有2个数n,m. 接下来n行每行一个正整数Li,表示第i根木棍的长度.

Output

输出有2个数, 第一个数是总长度最大的一段的长度最小值, 第二个数是有多少种砍的方法使得满足条件.

Sample Input

3 2
1
1
10

Sample Output

10 2

HINT

两种砍的方法: (1)(1)(10)和(1 1)(10)

数据范围

n<=50000, 0<=m<=min(n-1,1000).

1<=Li<=1000.

Source

BZOJ 1044: [HAOI2008]木棍分割(二分答案 + dp)的更多相关文章

  1. BZOJ 1044 HAOI2008 木棍切割 二分答案+动态规划

    题目大意:给定n个连在一起的木棍.分成m+1段.使每段最大值最小,求最大值的最小值及最大值最小时切割的方案数 第一问水爆了--二分答案妥妥秒过 第二问就有些难度了 首先我们令f[i][j]表示用前j个 ...

  2. 【BZOJ】1044: [HAOI2008]木棍分割 二分+区间DP

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1044 Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, ...

  3. [BZOJ1044][HAOI2008]木棍分割 二分+贪心+dp+前缀和优化

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4112  Solved: 1577 [Submit][St ...

  4. [BZOJ 1044] [HAOI2008] 木棍分割 【二分 + DP】

    题目链接:BZOJ 1044 第一问是一个十分显然的二分,贪心Check(),很容易就能求出最小的最大长度 Len . 第二问求方案总数,使用 DP 求解. 使用前缀和,令 Sum[i] 为前 i 根 ...

  5. bzoj 1044 [HAOI2008]木棍分割(二分+贪心,DP+优化)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1044 [题意] n根木棍拼到一起,最多可以切m刀,问切成后最大段的最小值及其方案数. ...

  6. bzoj 1044: [HAOI2008]木棍分割【二分+dp】

    对于第一问二分然后贪心判断即可 对于第二问,设f[i][j]为已经到j为止砍了i段,转移的话从$$ f[i][j]=\sigema f[k][j-1] (s[j]-s[k-1]<=ans) 这里 ...

  7. BZOJ 1044: [HAOI2008]木棍分割 DP 前缀和优化

    题目链接 咳咳咳,第一次没大看题解做DP 以前的我应该是这样的 哇咔咔,这tm咋做,不管了,先看个题解,再写代码 终于看懂了,卧槽咋写啊,算了还是抄吧 第一问类似于noip的那个跳房子,随便做 这里重 ...

  8. bzoj 1044 [HAOI2008]木棍分割——前缀和优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1044 前缀和优化. 但开成long long会T.(仔细一看不用开long long) #i ...

  9. BZOJ 1044: [HAOI2008]木棍分割

    Description 求 \(n\) 根木棍长度为 \(L\) ,分成 \(m\) 份,使最长长度最短,并求出方案数. Sol 二分+DP. 二分很简单啊,然后就是方案数的求法. 状态就是 \(f[ ...

随机推荐

  1. poj2190

    #include <stdio.h> #include <stdlib.h> int main() { ]; ,i; scanf("%s",arr); ;i ...

  2. [LeetCode][Python]Regular Expression Matching

    # -*- coding: utf8 -*-'''https://oj.leetcode.com/problems/regular-expression-matching/ Implement reg ...

  3. 浅谈POSIX线程的私有数据

    当线程中的一个函数需要创建私有数据时,该私有数据在对函数的调用之间保持一致,数据能静态地分配在存储器中,当我们采用命名范围也许可以实现它使用在函数或是文件(静态),或是全局(EXTERN).但是当涉及 ...

  4. 网页平面设计 CSS

    1.在html中引入css的方法 1.行内式 行内式即在标记的style属性中设定CSS样式,这种方式本质上没有体现出CSS的优势,因此不推荐使用. 例如:<h1 style="属性名 ...

  5. poj3162 Walking Race

    题目大意:给一个树形图n个点(n-1条边),XXX要练习竞走,每次选定一个点k作为开始点,每次走从k开始能走的最长的一条路径(不要重边).要求出最长的连续的这样的k,假设连续有kx个,前提:这样kx条 ...

  6. Problem G: If We Were a Child Again

    Problem G: If We Were a Child AgainTime Limit: 1 Sec Memory Limit: 128 MBSubmit: 18 Solved: 14[Submi ...

  7. pyhon MySQLdb查询出来的数据设置为字典类型

    import MySQLdbimport MySQLdb.cursors cxn=MySQLdb.Connect(host='localhost',user='root',passwd='1234', ...

  8. JQ兼容性问题

    checkbox操作 1:设置为选中状态   $(this).prop("checked", true); 2:判断是否选中     $(this).is(":check ...

  9. JS计算两个日期相差几天

    function Computation(sDate1, sDate2){ var aDate, oDate1, oDate2, iDays aDate = sDate1.split("-& ...

  10. Q_D宏

    Qt 源码中有很多Q_Q和Q_D宏,使用这些宏的地方总会看到有q指针和d指针,查了查KDE文档,大体搞清了其中的机理,欧也!Qt的这些私有数据访问策略还是挺值得借鉴.下面就简单总结一下. 访问器 , ...