题目描述:
在印刷术发明之前,复制一本书是一个很困难的工作,工作量很大,而且需要大家的积极配合来抄写一本书,团队合作能力很重要。
当时都是通过招募抄写员来进行书本的录入和复制工作的, 假设现在要抄写m本书,编号为1,2,3...m, 每本书有1<=x<=100000页, 把这些书分配给k个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的。每个抄写员的速度是相同的,你的任务就是找到一个最佳的分配方案,使得所有书被抄完所用的时间最少。
输入:
输入可能包含多个测试样例。
第一行仅包含正整数 n,表示测试案例的个数。
对于每个测试案例,每个案例由两行组成,在第一行中,有两个整数m和 k, 1<=k<=m<=500。 在第二行中,有m个整数用空格分隔。 所有这些值都为正且小于100000。
输出:
对应每个测试案例,
输出一行数字,代表最佳的分配方案全部抄写完毕所需要的时间。
样例输入:
2
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100
样例输出:
1700
在印刷术发明之前,复制一本书是一个很困难的工作,工作量很大,而且需要大家的积极配合来抄写一本书,团队合作能力很重要。
当时都是通过招募抄写员来进行书本的录入和复制工作的, 假设现在要抄写m本书,编号为1,2,3...m, 每本书有1<=x<=100000页, 把这些书分配给k个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的。每个抄写员的速度是相同的,你的任务就是找到一个最佳的分配方案,使得所有书被抄完所用的时间最少。
输入:
输入可能包含多个测试样例。
第一行仅包含正整数 n,表示测试案例的个数。
对于每个测试案例,每个案例由两行组成,在第一行中,有两个整数m和 k, 1<=k<=m<=500。 在第二行中,有m个整数用空格分隔。 所有这些值都为正且小于100000。
输出:
对应每个测试案例,
输出一行数字,代表最佳的分配方案全部抄写完毕所需要的时间。
样例输入:
2
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100
样例输出:
1700
200
这道题目跟另一道常见的题目类似
问题描述:
把一个包含n个正整数的序列划分成m个连续的子序列。设第i个序列的各数之和为S(i),求所有S(i)的最大值最小是多少?
例如序列1 2 3 2 5 4划分为3个子序列的最优方案为 1 2 3 | 2 5 | 4,其中S(1),S(2),S(3)分别为6,7,4,那么最大值为7;
如果划分为 1 2 | 3 2 | 5 4,则最大值为9,不是最小。
可以采用 http://blog.youkuaiyun.com/nanjunxiao/article/details/8145971所描述的方法,但是在面试那种紧张的环境下还是走一些正常路,贪心加二分的思想有一定的技巧性。所以我想直接通过动态规划去解,这样更走寻常路。也解释了下面评论给出的疑问,为什么不用贪心加二分可以看出来这是一道二维动态规划的问题
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <deque>
using namespace std;
//m书的本书,k抄写员的个数
int dp[505][505];
int data[505]={100, 200, 300, 400, 500, 600, 700, 800, 900}; //每本书的页数
#define max(a, b) (a > b ? a : b)
#define INF 100000000
int GetMax(int m , int k){
int i,j,l,jj,sum;
dp[0][1] = 0;
for (j = 1; j <= m; j ++)
dp[j][1] = dp[j - 1][1] + data[j];
for (l = 2; l <= k; l ++){
for (j = l; j <= m - (k - l); j ++){
sum = 0;
dp[j][l] = INF;
for (jj = j; jj >= l; jj --){
sum += data[jj];
if (max(dp[jj - 1][l - 1], sum) < dp[j][l])
dp[j][l] = max(dp[jj - 1][l - 1], sum);
}
}
}
return dp[m][k];
}
int main(void)
{
cout<<GetMax(9,3)<<endl;
system("pause");
return EXIT_SUCCESS;
}