复印书本
有M本书(编号为1,2,…,M),每本书都有一个页数(分别是P1,P2,…,PM)。 想将每本都复制一份。将这M本书分给K个抄写员(1<=K<=M<=500),每本书只能分配给一个抄写员进行复制。 每个抄写员至少被分配到一本书,而且被分配到的书必须是连续顺序的。复制工作是同时开始进行的, 并且每个抄写员复制一页书的速度都是一样的。所以, 复制完所有书稿所需时间取决于分配得到最多工作的那个抄写员的复制时间。 试找一个最优分配方案,使分配给每一个抄写员的页数的最大值尽可能小。 Input
第一行两个整数M、K;(K<=M<=500) 第二行M个整数,第i个整数表示第i本书的页数。
Output
输出为一个数,即分配给每一个抄写员的页数的最大值 Sample Input 9 3 1 2 3 4 5 6 7 8 9 Sample Output 17
题解(动态规划)
f[i][j] = min(max(f[i-l][j-1], d[i] - d[i-l]),f[i][j]); f[i][j]得到的数是其中要为j中其中一个人的分配最大且相对均衡(对于每个人)的数 i为书数,j为人数 l为最后一个人copy的书数,i-l为j-1copy的书数 对于f[i][j]的最好的解法,就是使用f[i-l][j-1]为(j-1)中的一个人的copy的页数 max为的得到(f[i-l][j-1])和(剩下的页数)的最大因为我们结果要的到最大的那个数 min 为了避免过大使分给每个人的页数相差过大(要求我们每个人分到的要对平衡所用时间最小) import java.util.Scanner; public class copy_book { static int m,k;//书本,人数 static int[] a;//第i本书有的页数 static int[][] f;//f[i][j] i本书j个人 static int[] d;//第i本书的总页数的d[i] public static void main(String[] args) { Scanner in = new Scanner(System.in); m = in.nextInt(); k = in.nextInt(); a = new int[m + 1]; d = new int[m + 1]; f = new int[m + 1][m + 1]; for (int i = 0; i <= m; i++) for (int j = 0; j <=m ; j++) f[i][j] = 100000; for (int i = 1; i <=m; i++) { a[i] = in.nextInt(); d[i] = d[i - 1] + a[i]; f[i][1] = d[i]; } for (int j = 2; j <= k; j++) { for (int i = j; i <= m; i++) { for (int l = 1; l <= i - 1; l++) { if (Math.max(f[i - l][j - 1], d[i] - d[i - l]) < f[i][j]) f[i][j] = Math.max(f[i - l][j - 1], d[i] - d[i - l]); } System.out.print("f["+i+"]["+j+"]="+f[i][j]+" "); } System.out.println(); } System.out.println(f[m][k]); } }