揹包問題

一種雙核CPU的兩個核能夠同時的處理任務,現在有n個已知數據量的任務需要交給CPU處理,假設已知CPU的每個核1秒可以處理1kb,每個核同時只能處理一項任務。n個任務可以按照任意順序放入CPU進行處理,現在需要設計一個方案讓CPU處理完這批任務所需的時間最少,求這個最小的時間。

輸入描述:

輸入包括兩行:
第一行爲整數n(1 ≤ n ≤ 50)
第二行爲n個整數length[i](1024 ≤ length[i] ≤ 4194304),表示每個任務的長度爲length[i]kb,每個數均爲1024的倍數。

輸出描述:

輸出一個整數,表示最少需要處理的時間


import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int[] arr = new int[n];
            int sum = 0;
            for (int i = 0; i < arr.length; i ++) {
                arr[i] = sc.nextInt() >> 10;
                sum += arr[i];
            }
            // dp[j]表示在容量爲j的情況下可存放的重量
            // 如果不放arr[i]重量爲dp[j],如果放arr[i]重量爲dp[j-arr[i]]+arr[i];
            int[] dp = new int[sum / 2 + 1];
            for (int i = 0; i < n; i ++) {
                for (int j = sum / 2; j >= arr[i]; j --) {
                    dp[j] = Math.max(dp[j], dp[j - arr[i]] + arr[i]);
                }
            }
            System.out.println(Math.max(dp[sum / 2], sum - dp[sum / 2]) << 10);
        }
    }
}
解析:

核心代碼就是以上16,17,18三行,實際就用了01揹包空間優化的策略。 思路:根據題目意思,兩個CPU平攤任務,然後輸出執行這些任務的最小時間,最理想的情況是,每個CPU執行的任務佔所有任務的總時間的一半(wholeTime/2),這樣兩個CPU執行的時間差就是最小的,輸出的結果就是最小的,但任務只能由一個CPU獨立完成,所以單個任務的執行時間已經是不可分割的了。解決的辦法就是儘量讓單個CPU執行的任務總時間接近wholeTime/2,越接近這個值,則這個CPU和另一個CPU的執行時間差就必定越小。也就能得到最優解,所以只要討論一個CPU即可,而且希望它的執行時間越接近wholeTime/2就越好,這就與01揹包問題掛上鉤了,問題轉化爲限制揹包的容量爲wholeTime/2,每個任務轉化爲每個物品,物品的價值和大小都是任務的執行時間,這樣一來,只要求得揹包總價值最大即可得到原問題的答案了。

完成任務有個總時間,2個cpu 執行 最快的 就是 一個人執行 一半,
// dp[j]表示在容量爲j的情況下可存放的重量
// 如果不放arr[i]重量爲dp[j],如果放arr[i]重量爲dp[j-arr[i]]+arr[i];
任務的value : 1 3 3 3 7 ; 任務數量爲 1 1 1 1 ;單個cpu 最多完成爲: sum/2=8;單個CPU 分別循環 1 ,2,3,4 個任務; 以4 爲例 最大可執行 4個任務;dp[8], 如果把4 任務放入則 ,d[j]=arr[4]+ 剩下的能放置的質量;d[8]=arr[4]+d[8-arr[4]] 第四個任務的value ;// 循環後會得到最大值 ;

假定

揹包的最大容量爲W,N件物品,每件物品都有自己的價值和重量,將物品放入揹包中使得揹包內物品的總價值最大。

Paste_Image.png

  1. public class sf {  
  2.   
  3.     public static void main(String[] args) {  
  4.         // TODO Auto-generated method stub  
  5.         int[] weight = {3,5,2,6,4}; //物品重量  
  6.         int[] val = {4,4,3,5,3}; //物品價值  
  7.         int m = 12; //揹包容量  
  8.         int n = val.length; //物品個數  
  9.           
  10.         int[] f = new int[m+1];  
  11.         for(int i=0;i<f.length;i++){     //不必裝滿則初始化爲0  
  12.             f[i] = 0;  
  13.         }  
  14.         for(int i=0;i<n;i++){  
  15.             for(int j=f.length-1;j>=weight[i];j--){  
  16.                 f[j] = Math.max(f[j], f[j-weight[i]]+val[i]);  
  17.             }  
  18.         }  
  19.         for(int i=0;i<f.length;i++){  
  20.             System.out.print(f[i]+" ");  
  21.         }  
  22.         System.out.println();  
  23.         System.out.println("最大價值爲"+f[f.length-1]);  
  24.     }  
  25. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章