POJ 2362

知识点:dfs(深度优先搜索)

题解:基本的dfs搜索判断可行性问题。一般的dfs搜索,如果不加剪枝,复杂度是指数级的,所以必须要能发掘出优秀的剪枝条件;

在本题中,一般有如下剪枝:

①:所有线段的长度之和必须为4的倍数;
②:搜索之前,把所有线段按从大到小排序,因为长度越长,在拼凑时的灵活度就越低;
③:当能拼凑出3根等长的线段时,第四根就无须再搜了;
④:当用某一条线段无法得出可行解时,和它等长的,一样不可以;

有了以上四个剪枝条件,这题就可以过了;

add:这题理解之后可以去看看poj 1011,那题是本题的加强版,所以光凭以上4个剪枝还是无法通过,大家要接着发掘剪枝条件;

 

 

 

 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<map>
 8 #include<string>
 9 #include<cmath>
10 #include<queue>
11 #define N 1005
12 #define M 10
13 #define MAXN 1000005
14 #define mod 1000000000
15 #define ll long long
16 using namespace std;
17 
18 int n,T;
19 int a[N];
20 int flag;
21 int sum;
22 int ma;
23 int l;
24 int vis[N];
25 
26 bool cmp(int x,int y)
27 {
28     return x>y;
29 }
30 
31 int DFS(int done,int left,int cur)
32 {
33   //  printf(" done=%d left=%d cur=%d\n",done,left,cur);
34     if(left==0){
35         if(done==3) return 1;
36         else{
37             if(DFS(done+1,l,1)==1) return 1;
38             else return 0;
39         }
40     }
41     else{
42         for(int i=cur;i<=n;i++){
43             if(vis[i]==1) continue;
44             if(a[i]>left) continue;
45             vis[i]=1;
46             if(DFS(done,left-a[i],i)==1) return 1;
47             else{
48                 vis[i]=0;
49                 int j=i+1;
50                 while(j<=n && a[j]==a[i]){
51                     j++;
52                 }
53                 i=j-1;
54             }
55         }
56         return 0;
57     }
58 }
59 
60 int main()
61 {
62     int i,j,k;
63   //  freopen("data.txt","r",stdin);
64     scanf("%d",&T);
65     //while(scanf("%d",&n)!=EOF)
66     while(T--)
67    // for(cnt=1;cnt<=T;cnt++)
68     {
69         scanf("%d",&n);
70         memset(vis,0,sizeof(vis));
71         sum=flag=0;ma=0;
72         for(i=1;i<=n;i++){
73             scanf("%d",&a[i]);
74             sum+=a[i];
75             ma=max(a[i],ma);
76         }
77         if(sum%4!=0 || ma>sum/4){
78             printf("no\n");
79             continue;
80         }
81         l=sum/4;
82         sort(a+1,a+1+n,cmp);
83         vis[1]=1;
84         if(DFS(0,l-a[1],1)==1)
85             printf("yes\n");
86         else
87             printf("no\n");
88 
89     }
90 
91     return 0;
92 }

 

转载于:https://www.cnblogs.com/njczy2010/p/3901296.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值