CF1552D题解
CF1552D题解
思路
首先, 的正负不重要,如果 ,那么就有 ,读入时将 全部转化为正数。
若满足 ,那么就可以构造出 序列,否则不行。
从左到右遍历一遍 序列,动态规划推出所有可以组成的和,并判断是否满足上式,时间复杂度 。
#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(); }
现在抛出一个不难验证的结论:若 ( 为 或 )
那么就可以构造出序列 ,否则不能。
那么对于 序列中的所有数,有三种情况:
- 不在上面式子中。
- 在上式中,为 。
- 在上式中, 为 。
共 种状态(因为不能全部不在上式中,所以减去 种情况)。
遍历 次这种状态,若有一种情况符合上式,那么就输出 yes
,时间复杂度 。
#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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步