G. Subsequence Addition
标签
规律、数学
链接
传送门、
结论
当前前缀和小于这个数就是NO,其他是YES(1处特殊)
证明
n=1时,sum1=1,均可以到达n=1时,sum_1=1,均可以到达n=1时,sum1=1,均可以到达
假设n=k时,sumk中所有的数均可以到达假设n=k时,sum_k中所有的数均可以到达假设n=k时,sumk中所有的数均可以到达
那么n=k+1时,sumk+1=sumk+ak+1那么n=k+1时,sum_{k+1}=sum_k+a_{k+1}那么n=k+1时,sumk+1=sumk+ak+1
其中小于等于sumk部分均有子集和存在,又因为ak+1⩽sumk其中小于等于sum_k部分均有子集和存在,又因为a_{k+1}\leqslant sum_k其中小于等于sumk部分均有子集和存在,又因为ak+1⩽sumk
而且,sumk+1是全集,必然存在而且,sum_{k+1}是全集,必然存在而且,sumk+1是全集,必然存在
对于sumk+1,sumk+2...,sumk+ak+1对于sum_{k}+1,sum_k+2...,sum_k+a_{k+1}对于sumk+1,sumk+2...,sumk+ak+1
只需sumk+1,减去ak+1−x⩽sumk(0⩽x
得证k+1的时候,小于等于sumk+1的部分均有子集存在得证k+1的时候,小于等于sum_{k+1}的部分均有子集存在得证k+1的时候,小于等于sumk+1的部分均有子集存在
结论成立结论成立结论成立
实现
#include
#define ll long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define ls (id << 1)
#define rs (id << 1 | 1)
using namespace std;
typedef pair 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;
}