【DFS】DLUToj-1215-组合数字

来源:互联网 发布:一句话webshell 编辑:程序博客网 时间:2024/05/30 22:58

题目链接:http://acm.dlut.edu.cn/problem.php?id=1215

题目描述:给出N个整数,每个数范围在[-1000,1000],问能不能在N个数中选出一些数(但不可以不选,且每个数最多只能被选择一次),使他们的和为0

解题思路:OJ上竟然有人发邮件问我。。点开一看还是我没做过的题。。一道DFS

好吧。。去敲了一下。显然得剪枝一下才能过,懒得剪枝WA了一下,改完就过了

把数字分成正数和负数
sum大于0从负数那边找
sum小于0从正数那边找

竟然还跑了0ms。。。无语

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int arr[50],vis[50];int n,sum,found,mid,fu,zh;void dfs(int i){    //cout<<sum<<endl;    if(found)return;    if(!sum)        found=1;    else    {        vis[i]=1;        int j;        if(sum>0)        {            for(j=fu+1;j<mid;j++)            {                if(!vis[j])                {                    vis[j]=1;                    sum+=arr[j];                    fu++;                    dfs(j);                    fu--;                    vis[j]=0;                    sum-=arr[j];                }            }        }        else        {            for(j=zh++;j<n;j++)            {                if(!vis[j])                {                    vis[j]=1;                    sum+=arr[j];                    dfs(j);                    vis[j]=0;                    sum-=arr[j];                }            }        }    }}int solve(){    int i;    for(i=0;i<n;i++)    {        if(arr[i]>0)return 0;        sum=arr[i];        found=0;        fu=i;zh=mid;        memset(vis,0,sizeof(vis));        dfs(i);        if(found)            return 1;        return 0;    }}int main(){    freopen("input.txt","r",stdin);    int T,i;    scanf("%d",&T);    while(T--)    {        memset(arr,0,sizeof(arr));        scanf("%d",&n);        for(i=0;i<n;i++)            scanf("%d",&arr[i]);        sort(arr,arr+n);        for(i=0;i<n;i++)        {            if(arr[i]>0)            {                mid=i;break;            }        }        int ans=solve();        if(ans)            printf("Yes\n");        else            printf("No\n");    }    return 0;}


0 0
原创粉丝点击