题目:Problem - 1552D - Codeforces
大意:给出一个大小为 n 的 a 序列,问是否有一个 b 序列满足 a[i] = b[j] - b[k];
思路:a[i]看成边,b[i]看成点,可以构造一些点,让每种a[i]边都能用到(点数<=边数),可以想到不符合条件的情况就是 点数=边数+1;原因其实就是这个图中没有一个环,所以假如说我们能构造出至少一个环那么最差的情况就是(点数=边数)也是符合题意的
因此我们用dfs找出几条边看看能不能摆一个环,因此每条边都有正着摆(+| a[i] |)反着摆(-|a[i]|)
和不用3种情况(都不用要排除掉)
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,a[10010],f=0;
void dfs(int x,int k,int lim)
{
int i,j;
if(k==n+1)
{
if(x==0&&lim) f=1;
return;
}
dfs(x+a[k],k+1,lim+1);
if(f) return;
dfs(x-a[k],k+1,lim+1);
if(f) return;
dfs(x,k+1,lim);
if(f) return;
}
int main()
{
int i,j,w;
scanf("%d",&w);
while(w--)
{
scanf("%d",&n);
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
f=0;
dfs(0,1,0);
if(f) printf("YES\n");
else printf("NO\n");
}
return 0;
}