2016級算法第三次上機-D.雙十一的抉擇
阿新 • • 發佈:2017-12-04
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.雙十一的抉擇