题目
现在要把m本有顺序的书分给k个人复制(抄写),每个人的抄写速度都一样,一本书不允许分给两个或两个以上的人抄写,分给每个人的书,必须是连续的,比如不能把第一、第三、第四本书给同一个人抄写。
现在请你设计一种方案,使得复制时间最短。复制时间为抄写最多的人用去的时间。
输入
第一行两个整数,m,k(k<=m<=500)
第二行为m个整数,第i个数表示第i本书的页数。
输出
最短时间
输入样例
9 3
1 2 3 4 5 6 7 8 9
输出样例
17
解题思路
这道题我们可以用f[i][j]表示前i个人抄前j本书的最大时间,然后我们可以枚举抄的位置。列出动态转移方程f[i][j]=min(max(f[i-1][k],s[j]-s[k]),f[i][j])。
代码
#include<cstdio>
#include<iostream>
using namespace std;
int n,m,s[501],f[501][501],x,maxs;
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++){scanf("%d",&x);s[i]=s[i-1]+x;//前缀和,这样就可以用s[j]-s[i-1]求到i到j个数的值}memset(f,127/3,sizeof(f));//赋值一个很大的整数for (int i=0;i<=n;i++) f[1][i]=s[i];//只给一个人抄的工作量for (int i=2;i<=m;i++){//插入第i个人for (int j=1;j<=n;j++){//枚举前j本书for (int k=1;k<j;k++){//枚举插入位置f[i][j]=min(max(f[i-1][k],s[j]-s[k]),f[i][j]);//max(f[i-1][k],s[j]-s[k])表示求插在当前位置时的最大时间//然后求该段的最小值}}}printf("%d",f[m][n]);//输出
}