Codeforces Round #683 (Div. 2, by Meet IT)C. Knapsack(貪心+思維)
阿新 • • 發佈:2020-11-16
題意
給你一個上界\(W\)和一系列權值\(w_i\),讓你找到權值中任意一個或多個的和滿足\((W + 1) / 2\leq sum \leq W\)
思路
從大到小貪心。
證明:
假設我貪到了一個這個數本身是滿足\((W + 1) / 2\leq sum \leq W\)那麼我可以直接輸出。
假設所有的權值都是不滿足\((W + 1) / 2\leq sum \leq W\),那麼任意兩個的和都是小於\(W\)的,那麼當他們加起來和大於\((W + 1) / 2\)時輸出就行,否則就是\(-1\)
#include<bits/stdc++.h> using namespace std; #define int long long const int maxn = 2e5 + 10; struct NODE { int id, val; NODE(){} NODE(int _id, int _val): id(_id), val(_val){} bool operator < (const NODE& x) const { return val > x.val; } } a[maxn]; void solve() { int n, W; cin >> n >> W; int l = (W + 1) / 2, r = W; vector<int>ans; for (int i = 1; i <=n; ++i) { cin >> a[i].val; a[i].id = i; } sort(a + 1, a + 1 + n); int sum = 0; for (int i = 1; i <= n; ++i) { if(a[i].val > r) continue; ans.push_back(a[i].id); sum += a[i].val; if (sum >= l && sum <= r) { cout << ans.size() << "\n"; for (int i = 0; i < ans.size(); ++i) { if (i) cout << " "; cout << ans[i]; } cout << endl; return ; } } cout << -1 << "\n"; } signed main() { int t; cin >> t; while (t--) { solve(); } }