poj 1505 Copying Books
Time Limit: 3000MS | Memory Limit: 10000K | |
Total Submissions: 7053 | Accepted: 2200 |
Description
Once upon a time, there was a theater ensemble that wanted to play famous Antique Tragedies. The scripts of these plays were divided into many books and actors needed more copies of them, of course. So they hired many scribers to make copies of these books. Imagine you have m books (numbered 1, 2 ... m) that may have different number of pages (p1, p2 ... pm) and you want to make one copy of each of them. Your task is to divide these books among k scribes, k <= m. Each book can be assigned to a single scriber only, and every scriber must get a continuous sequence of books. That means, there exists an increasing succession of numbers 0 = b0 < b1 < b2, ... < bk-1 <= bk = m such that i-th scriber gets a sequence of books with numbers between bi-1+1 and bi. The time needed to make a copy of all the books is determined by the scriber who was assigned the most work. Therefore, our goal is to minimize the maximum number of pages assigned to a single scriber. Your task is to find the optimal assignment.
Input
Output
If there is more than one solution, print the one that minimizes the work assigned to the first scriber, then to the second scriber etc. But each scriber must be assigned at least one book.
Sample Input
2
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100
Sample Output
100 200 300 400 500 / 600 700 / 800 900
100 / 100 / 100 / 100 100
题意:m本书,k个人,用/划分k-1个区间,怎样划分使区间最大的和最小。如果有相同的划分,就输出第一个区间最小的,如果第一区间相等,输出第二区间最小的,依次类推。
每个人都必须有一本书复制,每本书都要复制。
分析:用区间dp,dp[i][j]表示前j个人复制i本书,最大时间中最小。用path数组来记录/的位置。
dp[i][j]是枚举第j个人,前j-1个人最小dp[j-1][j-1],则第j个人就要复制sum[j,i],sum[j,i]表示第j本书到第i本书的页数的总和。
j-1个人也可以复制比j-1更多的书,用一个变量v表示前j-1的人获得的书,v可是在j-1和i-1变化,因为必须要留一本给第j个人。
则前j-1个人就是dp[v][j-1],则第j个人复制的书就是sum[v+1,i]表示第v+1本书到第i本书的页数之和。j-1<=v<=i+1,v的变化来求出第j个人最大的时间。在总体dp[i][j]中挑出最小的。
因此状态转移方程: dp[i][j]=min(dp[i][j],max(dp[v][j-1],sum[v+1,i))
1<=i<=m,1<=j<=k&&j<=i,j-1<=v<=i+1
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[][];
int main()
{
int i,t,a[],k,m,j,v,sum[],temp,p,path[];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&k);
sum[]=;
for(i=;i<=m;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
}
memset(dp,,sizeof(dp));
memset(path,,sizeof(path));//记录的/的路径一定要清零,不然影响下一次的结果。
for(i=;i<=m;i++)
{
for(j=;j<=i&&j<=k;j++)
{
if(j==)
dp[i][j]=sum[i];
else
{
for(v=j-;v<=i-;v++)
{ temp=max(dp[v][j-],sum[i]-sum[v]);
if(dp[i][j]==||dp[i][j]>=temp)
dp[i][j]=temp;
}
}
}
}//dp[m][k]表示前k个人复制前m本书所需要的最大时间中最小.
p=;j=k-;//有k个人只有k-1的标记处。
for(i=m;i>=;i--)
{
p+=sum[i]-sum[i-]; if(p>dp[m][k]||i==j)//p从后面求和,如果p大于dp[m][k],p就可以记录一下,因为每一段
//路径除了那个最大的区间之外相等,其余都小于dp[m][k],i==j是每本书都仅有一个人对应。
{
path[j--]=i+;
p=sum[i]-sum[i-];
}
}
v=;
for(i=;i<m;i++)
{
printf("%d ",a[i]);
if(i+==path[v])
{
printf("/ ");
v++;
}
}
printf("%d\n",a[m]);
}
return ;
}
/*
2
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100
*/
poj 1505 Copying Books的更多相关文章
- 【POJ】1505 Copying Books
此题主要采用DP思路,难点是求解"/",需要考虑划分数量不够的情况,先采用DP求解最优解,然后采用贪心求解slash.防止中间结果出错,使用了unsigned int. #incl ...
- UVa 714 Copying Books(二分)
题目链接: 传送门 Copying Books Time Limit: 3000MS Memory Limit: 32768 KB Description Before the inventi ...
- 抄书 Copying Books UVa 714
Copying Books 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/B 题目: Descri ...
- UVA 714 Copying Books 二分
题目链接: 题目 Copying Books Time limit: 3.000 seconds 问题描述 Before the invention of book-printing, it was ...
- uva 714 Copying Books(二分法求最大值最小化)
题目连接:714 - Copying Books 题目大意:将一个个数为n的序列分割成m份,要求这m份中的每份中值(该份中的元素和)最大值最小, 输出切割方式,有多种情况输出使得越前面越小的情况. 解 ...
- UVA 714 Copying Books 最大值最小化问题 (贪心 + 二分)
Copying Books Before the invention of book-printing, it was very hard to make a copy of a book. A ...
- POJ1505&&UVa714 Copying Books(DP)
Copying Books Time Limit: 3000MS Memory Limit: 10000K Total Submissions: 7109 Accepted: 2221 Descrip ...
- Copying Books
Copying Books 给出一个长度为m的序列\(\{a_i\}\),将其划分成k个区间,求区间和的最大值的最小值对应的方案,多种方案,则按从左到右的区间长度尽可能小(也就是从左到右区间长度构成的 ...
- 【NOIP提高组2015D2T1】uva 714 copying books【二分答案】——yhx
Before the invention of book-printing, it was very hard to make a copy of a book. All the contents h ...
随机推荐
- hdu 4447 Yuanfang, What Do You Think?
思路: 这题有个结论也可以自己归纳: 对于给定的n,其约数用pi表示 T(n)=T(p1)T(p2)……T(pn)T(n') 其中T(n')是这个式子所独有的也就是 T(n')=(x^n-1)/T(p ...
- hdu 4599 Dice 概率DP
思路: 1.求f[n];dp[i]表示i个连续相同时的期望 则 dp[0]=1+dp[1] dp[1]=1+(5dp[1]+dp[2])/6 …… dp[i]=1+(5dp[1 ...
- jmeter 使用聚合报告分析jtl文件
对于jmeter测试生成产生的jtl文件除了使用jemter插件来产生csv或者结果,还可以直接用聚合报告来打开,下面来介绍一下怎么操作. 1. 产生jtl文件 注意,默认情况下聚合报告插件只能分析聚 ...
- 分析windows宿主机Ping不通linux虚拟机的其中一种情况
ping不通的情况是由于设置网络选项的时候,可以看到界面名称的选择如下(当前选择的是无线网卡驱动):
- http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html
http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html http://www.cnblogs.com/langtianya/a ...
- lintcode :最长上升连续子序列
题目: 最长上升连续子序列 给定一个整数数组(下标从 0 到 n-1, n 表示整个数组的规模),请找出该数组中的最长上升连续子序列.(最长上升连续子序列可以定义为从右到左或从左到右的序列.) 样例 ...
- Matlab程序 转C++/Opencv基于Mat 不可不知的17个函数
1.matlab中的imread相当于OpenCV中的cvLoadImage(imageName, CV_LOAD_IAMGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR): ...
- 对象的类型转换P109
类作为一种应用数据类型,和基本数据类型的变量一样.不同类中存在对象与对象之间的类型转问题,对象的类型转换只能在 具有继承关系的 父类对象-----子类对象 之间进行 子类通常比父类拥有更多的域和 ...
- Zookeeper、HBase的伪分布
1.Zookeeper伪分布的部署(3个节点) 所谓的“伪分布式集群”就是在一台服务器中,启动多个Zookeeper实例.“完全分布式集群”是每台服务器,启动一个Zookeeper实例. 1.1.解压 ...
- hdu 携程全球数据中心建设 (球面距离 + 最小生成树)
题目 #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib&g ...