G. Subsequence Addition
标签
规律、数学
链接
传送门、
结论
当前前缀和小于这个数就是NO,其他是YES(1处特殊)
证明
n
=
1
时,
s
u
m
1
=
1
,
均可以到达
n=1时,sum_1=1,均可以到达
n=1时,sum1=1,均可以到达
假设
n
=
k
时,
s
u
m
k
中所有的数均可以到达
假设n=k时,sum_k中所有的数均可以到达
假设n=k时,sumk中所有的数均可以到达
那么
n
=
k
+
1
时,
s
u
m
k
+
1
=
s
u
m
k
+
a
k
+
1
那么n=k+1时,sum_{k+1}=sum_k+a_{k+1}
那么n=k+1时,sumk+1=sumk+ak+1
其中小于等于
s
u
m
k
部分均有子集和存在,又因为
a
k
+
1
⩽
s
u
m
k
其中小于等于sum_k部分均有子集和存在,又因为a_{k+1}\leqslant sum_k
其中小于等于sumk部分均有子集和存在,又因为ak+1⩽sumk
而且,
s
u
m
k
+
1
是全集,必然存在
而且,sum_{k+1}是全集,必然存在
而且,sumk+1是全集,必然存在
对于
s
u
m
k
+
1
,
s
u
m
k
+
2...
,
s
u
m
k
+
a
k
+
1
对于sum_{k}+1,sum_k+2...,sum_k+a_{k+1}
对于sumk+1,sumk+2...,sumk+ak+1
只需
s
u
m
k
+
1
,
减去
a
k
+
1
−
x
⩽
s
u
m
k
(
0
⩽
x
<
a
k
+
1
)
只需sum_{k+1},减去a_{k+1}-x\leqslant sum_{k}(0\leqslant x < a_{k+1})
只需sumk+1,减去ak+1−x⩽sumk(0⩽x<ak+1)
即全集中取出这些子集,必然存在,
即全集中取出这些子集,必然存在,
即全集中取出这些子集,必然存在,
得证
k
+
1
的时候,小于等于
s
u
m
k
+
1
的部分均有子集存在
得证k+1的时候,小于等于sum_{k+1}的部分均有子集存在
得证k+1的时候,小于等于sumk+1的部分均有子集存在
结论成立
结论成立
结论成立
实现
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define ls (id << 1)
#define rs (id << 1 | 1)
using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 5;
int a[N];
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
if (a[1] != 1) {
cout << "NO\n";
return;
}
ll sum = 1;
for (int i = 2; i <= n; i++) {
if (a[i] > sum) {
cout << "NO\n";
return;
}
sum += a[i];
}
cout << "YES\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}