📂题解
🔖题解
2023-11-18 19:06阅读: 15评论: 0推荐: 0

CF1552D题解

CF1552D题解

思路

首先,ai 的正负不重要,如果 ai=bjbk,那么就有 ai=bkbj,读入时将 ai 全部转化为正数。

若满足 ai+aj++ak,那么就可以构造出 b 序列,否则不行。

从左到右遍历一遍 a 序列,动态规划推出所有可以组成的和,并判断是否满足上式,时间复杂度 O(T×n×max(ai))

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int T,n,dp[N],a[20];
void solve(){
for(int i=0;i<N;i++) dp[i]=0;
cin>>n; dp[0]=1; bool flag=false;
for(int i=0;i<n;i++){ cin>>a[i]; a[i]=a[i]<0?-a[i]:a[i]; }
for(int i=0;i<n;i++)
for(int j=N-1-a[i];j>=0;j--)
if(dp[j]){
if(dp[j+a[i]]==1) flag=true;
else dp[j+a[i]]=1;
}
cout<<(flag?"YES\n":"NO\n");
}
-
signed main(){
ios::sync_with_stdio(false);
for(cin>>T;T;T--) solve();
}

现在抛出一个不难验证的结论:若 aiopajopakopal=0op+
那么就可以构造出序列 b,否则不能。
那么对于 a 序列中的所有数,有三种情况:

  1. ai 不在上面式子中。
  2. ai 在上式中,op+
  3. ai 在上式中,op

3n1 种状态(因为不能全部不在上式中,所以减去 1 种情况)。

遍历 1 次这种状态,若有一种情况符合上式,那么就输出 yes,时间复杂度 O(n×3n)

#include<bits/stdc++.h>
using namespace std;
int T,n,a[20];
void solve(){
cin>>n; int k=pow(3,n);
for(int i=0;i<n;i++) cin>>a[i];
for(int i=1;i<k;i++){
int sum=0,tk=i;
for(int j=0;j<n;j++){
int s=tk%3; tk/=3;
if(s==2) s=-1;
sum+=s*a[j];
}
if(sum==0) return (void)(cout<<"YES\n");
}
cout<<"NO\n";
}
signed main(){
ios::sync_with_stdio(false);
for(cin>>T;T;T--) solve();
}

本文作者:merlinkkk

本文链接:https://www.cnblogs.com/merlinkkk/p/17832517.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   merlinkkk  阅读(15)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开