poj2362

来源:互联网 发布:手机直播源码 编辑:程序博客网 时间:2024/05/16 09:27

本题很早就看到过,一直拖到现在才做,本题就是一个排序+搜索+剪枝题,题意非常简单,说一下剪枝:

1为了早点剪枝,将优先选择边长较长的棒子

2棒子长度和是4 的倍数,最长的棒子小于边长,棒子个数要大于等于4

3符合2的情况下,我搜到3个边长,也意味着可以构成。

代码如下:

<span style="font-size:24px;">#include<stdio.h>#include<algorithm>#include<math.h>#include<iostream>using namespace std;int a[21];int mark[21];int n;int sum;int flag;bool cmp(int a,int b){    return a>b;}void dfs(int x,int dep,int s,int st){    int i;    if(flag==1)        return ;    if(dep==3)    {        flag=1;        return ;    }    for(i=st;i<=n;i++)    if(mark[i]==0)    {        if(s+a[i]<x)        {            if(i+1<=n)            {                mark[i]=1;                dfs(x,dep,s+a[i],i+1) ;                mark[i]=0;            }        }        else if(s+a[i]==x)        {            mark[i]=1;            dfs(x,dep+1,0,1);            mark[i]=0;        }       /* else        {            if(i+1<=n)                dfs(x,dep,s,i+1);        }         */    }    return ;}int main(){    int i;    int ca;    while(scanf("%d",&ca)!=EOF)    {        while(ca--)        {            scanf("%d",&n);            sum=0;            for(i=1;i<=n;i++)            {                scanf("%d",a+i);                sum+=a[i];                mark[i]=0;            }            sort(a+1,a+n+1,cmp);            if(sum%4!=0||n<4||a[1]>sum/4)            {                puts("no");                continue;            }            flag=0;            dfs(sum/4,0,0,1);            if(flag)            puts("yes");            else            puts("no");        }    }    return 0;}</span>

值得一提的是,我犯了一个错误,就是我一开始没有把注释的那段话删掉,就是说,在找到了dep条边长,当前累计和为s时,枚举每一条未被使用的边,发现这条边我加了超过边长时,我选择继续搜下去,状态是dfs(x,dep,s,i+1),我现在大概知道这样的做法可能不会错,但是可能会增加不少的时间,原因是我枚举下一个i的时候,和这个状态是一样的。重复搜索了!!!

0 0
原创粉丝点击