1. 程式人生 > >2016級算法第三次上機-D.雙十一的抉擇

2016級算法第三次上機-D.雙十一的抉擇

class cpp += else ++i 都是 created 參考 mat

915 雙十一的抉擇

思路

中等題。簡化題目:一共n個數,分成兩組,使得兩組的差最接近0,就是說要使兩組數都盡可能的接近sum/2。

思路還是很混亂的,不知道如何下手,暴力也挺難的,還不能保證對。想一想,從一堆數中取出一些使得和盡可能接近sum/2,把sum/2當作背包總體積,每個數字當作每件物品的體積,價值都是為1,求的就是最大價值。完完全全的01背包問題,問題解決,具體可見參考代碼。

這裏就不再詳細講解01背包了,請仔細研讀《背包九講》,務必學習到經典DP問題之背包問題的精髓。

分析

01背包的時間復雜度是 \(O(V*N)\)

參考代碼

//
// Created by AlvinZH on 2017/10/24.
// Copyright (c) AlvinZH. All rights reserved. // #include <cstdio> #include <cstring> int n, sum; int V;//背包體積 int N[1005];//把數量同時看作物品的體積和價值 int dp[50005]; int main() { while(~scanf("%d", &n)) { sum = 0; memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; ++i) { scanf("
%d", &N[i]); sum += N[i]; } V = sum / 2;//背包的體積 //01背包 for (int i = 1; i <= n; ++i) { for (int j = V; j >= N[i]; --j) { int temp = dp[j - N[i]] + N[i]; if(dp[j] < temp) dp[j] = temp; } } if
(sum - 2 * dp[V] == 0) printf("GF&SI\n"); else printf("%d\n", sum - 2 * dp[V]); } } /* 分析:一共n個數,分兩組,使得兩組的差最接近0,就是說要使兩組數都盡可能的接近sum/2。 * 很自然的想到這是在類似於取東西,看怎麽取得平均。 * 所以只需要對一組進行求算使它最接近sum/2,那樣的話另一組自然也是最接近的。 * 典型的01背包問題,sum/2作為背包總體積,每袋糖數量作為價值和體積,求最多可以裝多少。 */

2016級算法第三次上機-D.雙十一的抉擇