upc7834 送禮物
阿新 • • 發佈:2018-12-13
const () 正整數 txt 多個 尋找 amp 100% div
以後N行,每行一個正整數表示G[i],G[i]<= 2^31-1。
題目描述
作為懲罰,GY被遣送去幫助某神牛給女生送禮物(GY:貌似是個好差事)但是在GY看到禮物之後,他就不這麽認為了。某神牛有N個禮物,且異常沈重,但是GY的力氣也異常的大(-_-b),他一次可以搬動重量和在w(w<=2^31-1)以下的任意多個物品。GY希望一次搬掉盡量重的一些物品,請你告訴他在他的力氣範圍內一次性能搬動的最大重量是多少。
輸入
第一行兩個整數,分別代表W和N。以後N行,每行一個正整數表示G[i],G[i]<= 2^31-1。
輸出
僅一個整數,表示GY在他的力氣範圍內一次性能搬動的最大重量。
樣例輸入
20 5 7 5 4 18 1
樣例輸出
19
提示
對於20%的數據 N<=26
對於40%的數據 W<=2^26
對於100%的數據 N<=45 W<=2^31-1
最多45件禮物,如果直接暴力枚舉就會超時。將禮物分成兩半,分別枚舉出兩半中的各種組合,然後利用二分進行匹配,尋找最優解。
#include "bits/stdc++.h" using namespace std; const int maxn = 1e7 + 11; typedef long long ll; ll s[100]; ll sum[maxn]; ll ans = 0; int tot = 0; ll w, n; void dfs1(intnow, ll val) { if (now > n) { sum[++tot] = val; return; } if (val + s[now] <= w) dfs1(now + 1, val + s[now]); dfs1(now + 1, val); } int mid; void dfs2(int now, ll val) { if (now >= mid) { ll l = lower_bound(sum + 1, sum + tot + 1, w - val) - sum; ans= max(ans, val + sum[l-1]); return; } if (val + s[now] <= w) dfs2(now + 1, val + s[now]); dfs2(now + 1, val); } int main() { //freopen("input.txt", "r", stdin); cin >> w >> n; for (int i = 1; i <= n; i++) { cin >> s[i]; } sort(s + 1, s + 1 + n); mid = (n + 1) >> 1; dfs1(mid, 0); sort(sum + 1, sum + tot + 1); dfs2(1, 0); cout << ans << endl; return 0; }
upc7834 送禮物