动态规划:任务调度问题(双塔问题)

题目链接

两个CPU,处理N个任务,每个任务有一个处理时长(0~4096),要把这些任务全部处理完,如何调度才能最高效?
N个圆柱,要搭建两个塔,要使这两个塔高度之差尽量小,问较高的那座塔多高?

需要注意一个特殊情况:例如3 3 2 4
最合理的调度为:第一台CPU处理3、3;第二台CPU处理2、4。所以需要容忍的差异最大为两倍的最大值而非一倍最大值。

import java.util.Arrays;
import java.util.Scanner;

public class Main {
Main() {
    Scanner cin = new Scanner(System.in);
    int n = cin.nextInt();
    int[] a = new int[n + 1];
    for (int i = 1; i <= n; i++) a[i] = cin.nextInt() / 1024;
    int max = Arrays.stream(a).max().getAsInt() * 2;//这个地方很关键
    int[][] dp = new int[a.length][max + 2];
    for (int i = 0; i <= n; i++) for (int j = 0; j <= max; j++) dp[i][j] = n * max;
    dp[0][0] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= max; j++) {
            if (j - a[i] >= 0) {//如果交给任务少的机器
                dp[i][j - a[i]] = Math.min(dp[i][j - a[i]], dp[i - 1][j]);
            } else {
                dp[i][a[i] - j] = Math.min(dp[i][a[i] - j], dp[i - 1][j] + (a[i] - j));
            }
            //如果把任务交给任务多的机器
            if (j + a[i] <= max) {
                dp[i][j + a[i]] = Math.min(dp[i][j + a[i]], dp[i - 1][j] + a[i]);
            }
        }
    }
    int ans = Integer.MAX_VALUE;
    for (int i = 0; i <= max; i++) {
        ans = Math.min(ans, dp[n][i]);
    }
    System.out.println(ans * 1024);
//    for (int i = 0; i <= n; i++) {
//        for (int j = 0; j <= max; j++) {
//            System.out.print(dp[i][j]+" ");
//        }
//        System.out.println();
//    }
}

public static void main(String[] args) {
    new Main();
}
}

猜你喜欢

转载自www.cnblogs.com/weiyinfu/p/9502108.html