[Daimayuan] 背包(C++,模拟)

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/2sumw

请你帮 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 1t104, 1 ≤ ∑ n ≤ 2 ∗ 1 0 5 1≤\sum{n}≤2*10^5 1n2105, 1 ≤ w ≤ 1 0 18 1≤w≤10^{18} 1w1018, 0 ≤ w i ≤ 1 0 9 0≤w_i≤10^9 0wi109

样例输入1

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/2wiw,我们就可以输出 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 wiw/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;
}

你可能感兴趣的:(模拟与高精度,c++,模拟)