双核处理(动态规划的01背包问题)

来源:互联网 发布:甘比面相很好知乎 编辑:程序博客网 时间:2024/06/07 23:51

题目

一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间

输入描述:

输入包括两行: 第一行为整数n(1 ≤ n ≤ 50) 第二行为n个整数length[i](1024 ≤ length[i] ≤
4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。

输出描述:

输出一个整数,表示最少需要处理的时间

输入例子:

5 3072 3072 7168 3072 1024

输出例子:

9216

分析:

1、要让双核CPU执行的时间最少,其实就是要让两个核尽量同时结束。也就是要让一个核所执行的时间尽量逼近执行总时间的一半,也就是sum/2。
2、这样其实就将题目转化成了一个01背包问题。笔者对于01背包问题之前都是通过“深度优先搜索+回溯”的方式解决,但是在使用的时候往往会让复杂度过高或者执行时间过长,此例使用的是动态规划方式。
3、题目中其实有提示使用动态规划的01背包方式,题目中强调了“每个数均为1024的倍数”。

思路:

1、由于需要用总时间来创建数组,因此接收到数据后统一除以1024后存储。(最后输出的时候乘以1024)
2、i代表背包中处理了i个任务(可能装入可能不装入),j代表目前背包中有j的空间可以存放。
3、如果放入任务时间超过j,也就是p[i]>j,那么背包中就无法再放入任务,所以dp[i + 1][j] = dp[i][j]。反之,有两种可能,可能放入也可能不放入,这取决于此时放入的物品的性价比有没有之前放入的物品的性价比高,如果放入那么就为dp[i + 1][j] = dp[i][j - p[i]] + p[i],如果不放入就为dp[i + 1][j] =dp[i][j]。
4、最后附上这道题的数组实例:

0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 0 0 0 3 3 3 6 6 6 0 0 0 3 3 3 6 7 7 0 0 0 3 3 3 6 7 7 0 1 1 3 4 4 6 7 8  

代码:

import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner scan = new Scanner(System.in);        int n = scan.nextInt();        int[] p = new int[n];        int sum = 0;        for (int i = 0; i < n; i++) {            p[i] = scan.nextInt() / 1024;            sum += p[i];        }        int[][] dp = new int[n + 1][sum / 2 + 1];        for (int i = 0; i < n; i++)            for (int j = 1; j <=sum / 2; j++) {                if (j < p[i])                    dp[i + 1][j] = dp[i][j];                else                    dp[i + 1][j] = Math.max(dp[i][j], dp[i][j - p[i]] + p[i]);            }        System.out.println((sum - dp[n][sum / 2]) * 1024);    }}
原创粉丝点击