zoj_1909

来源:互联网 发布:php防cc攻击代码 编辑:程序博客网 时间:2024/06/06 08:48

很坑爹啊,浪费了一个晚上,其实我做过poj1011的。。那时候都顺利过了。。这个简化版居然纠结那么久。。最后发现没记录当前所到木棍,一开始觉得这个小小的剪枝就没必要啦,在poj1011时我就没做这个剪枝,都轻松过了。。。TLE了无数次,才决定试着改下。。⊙﹏⊙b汗。。0ms过了。。看来真的任何一点小小的代码都不容忽视的。。好吧,继续加油~

/*zoj_1909    搜索很经典的一道题。poj1011的简化版。。剪枝:1.从长到短排序,这样搜索失败时在离根部不远就结束的可能性大。2.长度总和%4==03.最短木棍大于边长度4.最后一条边不用搜5.对相同长度木棍分类,避免搜索的时候做重复的搜索。6.当前最长木棍必须用来组边。否则可直接退出。因为如果当前都不能用  后面也永远无法再用到。这个剪枝威力巨大。7.记录当前所到木棍的序号,即为代码中的index。这个在此题中关键,不  记录必然TLE(我一开始就没记,每次从0开始,TLE无数次)*/#include <iostream>#include <cstdio>#include <string.h>#include <algorithm>using namespace std;struct stick{    int len;    int num;}s[25];int m,ave;bool cmp( stick a,stick b ){return a.len>b.len;}bool dfs( int rest,int sum,int index ){    int i;    if( sum==ave )  return true; //剪枝4    for( i=index;i<m;i++ ) //剪枝7    {        if( s[i].num!=0 && s[i].len<=rest )        {            s[i].num--;            if( rest==s[i].len )            {                if( dfs( ave,sum-rest,0 ) )                    return true;            }            else if( dfs( rest-s[i].len,sum-s[i].len,i ) )                    return true;            s[i].num++;            if( rest==ave )   return false; //剪枝6        }    }    return false;}int main(){    int n,i,j,k,t,maxi,sum;    scanf( "%d",&n );    while( n-- )    {        scanf( "%d",&m );sum=0;  k=0;   maxi=-1;        for( i=0;i<m;i++ )        {            scanf( "%d",&t );            sum+=t ;            for( j=0;j<k;j++ )            {                if( s[j].len==t )  //剪枝5                {                    s[j].num++;                    break;                }            }            if( j==k )            {                s[k].len=t;                s[k].num=1;                k++;                if( maxi<t )    maxi=t;            }        }        m=k;        ave=sum/4;        if( sum%4!=0 || maxi>ave )  //剪枝2.剪枝3            printf( "no\n" );        else        {            sort( s,s+m,cmp );    //剪枝1            if( dfs( ave,sum,0 ) )   printf( "yes\n" );            else printf( "no\n" );        }    }    return 0;}