Codeforces Round 859 (Div. 4)(G)

文章讨论了一种关于子序列和的数学规律,即当n=1时,所有和均为1;假设n=k时,所有sum_k中的数均可达到,那么n=k+1时,通过递推sum_k+a_k+1,证明了小于等于sum_k+1的部分均有子集存在。程序实现验证了这一结论。
摘要由CSDN通过智能技术生成

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+1sumk
而且, 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+1xsumk(0x<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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值