infinity

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  36 随笔 :: 0 文章 :: 25 评论 :: 0 Trackbacks
http://acm.pku.edu.cn/JudgeOnline/problem?id=2362

很好很经典的深搜题,减枝不好很容易TLE,注意搜索顺序。先从大到小排序。这题跟1011差不多
1011黑书上有讲。最重要的减枝就是不能重复搜索,所以函数是int solve(int unused,int start,int left)
start就是拼当前这一条边的时候从那跟开始搜起。left表示当前这条边还剩多少拼完

Source Code

Problem: 2362 User: lovecanon
Memory: 204K Time: 16MS
Language: C Result: Accepted
 
#include<stdio.h>
#include
<string.h>
#include
<stdlib.h>

int len[21];
int used[21];
int n;
int side;
int start;

int cmp(const void *a,const void *b)
{
    
return *(int *)b-*(int *)a;
}

int solve(int unused,int start,int left)
{
    
int i;
    
if(unused==0&&left==0)  return 1;
    
if(unused==0return 0;

    
if(left==0
    {
        left
=side;
        
for(i=1;i<=n&&used[i];i++)
            
if(solve(unused,i,side)) return 1;
    }
    
    
for(i=start;i<=n;i++)
    {
        
if(!used[i]&&len[i]<=left)
        {
            
if(i>1)
            {
                
                
if(len[i]==len[i-1]&&!used[i-1])
                    
continue;
            }
            
if(left<len[n])  continue;
            used[i]
=1;

            
if(solve(unused-1,i,left-len[i])) return 1;
            used[i]
=0;
            
if(len[i]==left||left==side)  return 0;
        }

    }
    
return 0;
}
 
int main()
{
    
int T,sum,i;
    scanf(
"%d",&T);
    
while(T--)
    {
        sum
=0;
        scanf(
"%d",&n);
        len[
0]=0x7fffffff;
        
for(i=1;i<=n;i++)
        {
            scanf(
"%d",&len[i]);
            sum
+=len[i];
        }
        
if(sum%4) printf("no\n");
        
else
        {
            side
=sum/4;
            memset(used,
0,sizeof(used));
            qsort(len,n
+1,sizeof(len[0]),cmp);

            
if(len[1]>side) printf("no\n");
            
else if(solve(n,1,side))   printf("yes\n");
            
else printf("no\n");
        }
    }
    
return 0;
}

posted on 2008-09-20 04:46 infinity 阅读(1038) 评论(1)  编辑 收藏 引用 所属分类: acm

评论

# re: poj 2362 2009-07-05 09:36 luis
问一下牛人这句if(len[i]==left||left==side) return 0;的原理是什么?
  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理