c c cc cc有一个背包,背包的体积为 w w w,有 n n n个物品,每一个物品的体积为 a i a_i ai
c c cc cc希望将其中的一些物品放入他的背包中,他希望这些物品的体积之和至少是背包体积的一半,并且不超过背包的体积,即 ⌈ w / 2 ⌉ ≤ s u m ≤ w ⌈w/2⌉≤sum≤w ⌈w/2⌉≤sum≤w
请你帮 c c cc cc判断这些物品中有没有符合条件的物品组合,如果有输出" Y E S YES YES", 没有输出" N O NO NO"
c c cc cc至少会拿一个物品
第一行给出测试样例个数 T T T
对于每一个样例:
第一行给出一个 n n n和一个 w w w, n n n个物品,背包的总体积是 w w w
第二行给出一个序列 a 1 , . . . a n a_1,...a_n a1,...an,代表每一个物品的体积
如果有请输出" Y E S YES YES", 没有输出" N O NO NO"
1 ≤ t ≤ 1 0 4 1≤t≤10^4 1≤t≤104, 1 ≤ ∑ n ≤ 2 ∗ 1 0 5 1≤\sum{n}≤2*10^5 1≤∑n≤2∗105, 1 ≤ w ≤ 1 0 18 1≤w≤10^{18} 1≤w≤1018, 0 ≤ w i ≤ 1 0 9 0≤w_i≤10^9 0≤wi≤109
3
1 3
3
6 2
19 8 19 69 9 4
7 12
1 1 1 17 1 1 1
YES
NO
YES
学过背包问题的人不要被标题给误导了 q w q qwq qwq,因为本题背包容量过大根本不能动态规划
我们回归题意,重新出发
我们把物品分为三类:
(1)如果输入的物品体积大于背包容量,对我们来说就没有意义
(2)如果输入物品体积 ⌈ w / 2 ⌉ ≤ w i ≤ w ⌈w/2⌉≤w_i≤w ⌈w/2⌉≤wi≤w,我们就可以输出 Y E S YES YES
(3)如果输出物品体积 w i < ⌈ w / 2 ⌉ w_i<⌈w/2⌉ wi<⌈w/2⌉,我们就累计这类物品的总体积,如果最终总体积大于 ⌈ w / 2 ⌉ ⌈w/2⌉ ⌈w/2⌉,我们就可以输出 Y E S YES YES
对于第三类,不必担心物品总体积会直接超过 w w w,因为我们可以保证 w i < ⌈ w / 2 ⌉ w_i<⌈w/2⌉ wi<⌈w/2⌉,即 w i ≤ w / 2 w_i \le w/2 wi≤w/2
所以我们就可以在常数的时间复杂度下解决本题~
最后,AC代码如下
#include
using namespace std;
const int max_t = 1e4;
const int max_n = 2e5;
const long long max_w = 1e18;
const int max_item = 1e9;
long long t, n, w;
int main() {
cin >> t;
for (int i = 0; i < t; i++) {
cin >> n >> w;
long long item, sum = 0, ans = 0;
for (int i = 0; i < n; i++) {
cin >> item;
if (item <= w) {
if (item >= (w + 1) / 2) ans = 1;
else {
sum += item;
if (sum >= (w + 1) / 2) ans = 1;
}
}
}
if (ans) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}