Subsequence Addition
题意概要:
给定长度为
题目分析:
将
我们可以把题目抽象成如下:对于当前集合已经有了
我们对于每个
代码如下:
#include<bits/stdc++.h>
using namespace std;
int T;
int n;
const int N=5e3+10;
int a[N];
bool w[N];
int main(){
cin>>T;
while(T--){
cin>>n;int tem=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]==1)tem++;
}
sort(a+1,a+n+1);
memset(w,false,sizeof(w));
if(n==1){puts(a[1]==1?"YES":"NO");continue;}
if(n==2){puts(tem==2?"YES":"NO");continue;}
if(tem<2){puts("NO");continue;}
w[1]=true;bool flag=true;
for(int i=2;i<=n;i++){
if(!w[a[i]]){
flag=false;
break;
}
for(int j=5000;j>=a[i];j--)
w[j]|=w[j-a[i]];
}puts(flag?"YES":"NO");
}return 0;
}
注意到能取到的元素容易被转移很多次。这里只需要一个打表,或者有敏锐的直觉,你可以猜到一个结论:对于任意正整数
证明先咕一下,打表结果如下:
上面是
所以有了这个代码以后,只要求出
代码如下:
#include<bits/stdc++.h>
using namespace std;
int T;
typedef long long ll;
int n;
const int N=2e5+10;
ll a[N],s[N];
int main(){
cin>>T;
while(T--){
cin>>n;int tem=0;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
if(a[1]!=1){puts("NO");continue;}
bool flag=true;
for(int i=2;i<=n;i++)
if(s[i-1]<a[i]){
flag=false;
break;
}
puts(flag?"YES":"NO");
}return 0;
}
时间复杂度: