經歷了各種TLE,各種WA,還有一次RE,終于在網上找到兩句至理名言,靠這兩個剪枝,在北大上AC了這道錯了25次的1011.
但不行的是在Hdu,依然WA中,預知后事如何,請聽下回分解。
強大的剪枝!
1.搜索每根大木棍的時候,如果因為安放了第一段木棍就無法提供合理解的時,就不用去試探其他小木棍在第一段位置的情況了。所以回溯到上一個大木棍的搜索,是第一個大木棍的第一段出現問題,那么該長度肯定不符合要求。

2.每個大木棍的最后一段,如果不合要求,那么也不用去試圖去安放其他的小木棍了,直接回溯到上段木棍即可。因為,換成更小的木棍,即便也可使木棍填滿,小木棍也有可能在將來的時候無法安放。簡單的說,如果它不行,采用別的更小的木棍也不行;如果它可以,采用別的更小的木棍也一定可以。

#include<stdio.h>
#include
<algorithm>
#include
<string.h>
using namespace std;
int a[100],n,sum, get, mark[100];
int cmp(int c, int b)
{
    
return c>b;
}
int dfs(int nowlen, int nowget, int nowi)
{
    
for(int i=nowi; i<n; i++)
        
if(mark[i]==0 && nowlen>=a[i]){
            mark[i]
=1;
            
if(nowlen>a[i]){
                
if(dfs(nowlen-a[i], nowget, i+1)==1)
                    
return 1;
                
else if(nowlen==sum/get//剪枝1
                { mark[i]=0;    return 0; }
            }
            
else if(nowlen==a[i]){
                
if(nowget+1==getreturn 1;
                
if(dfs(sum/get, nowget+10)==1)
                    
return 1;
                
else{
                    mark[i]
=0;//剪枝2
                    return 0;
                }
            }
        mark[i]
=0;
        }


    
return 0;
}
int main()
{
    
int i,j,k;
    
while(scanf("%d",&n) && n){
        sum
=0;
        memset(a, 
0sizeof(a));
        
for(i=0; i<n; i++){
            scanf(
"%d",&a[i]);
            sum
+=a[i];
        }
        sort(a, a
+n, cmp);
        
get=sum/a[0];
        
while(sum%get!=0){
            
get--;
        }
        
while(1){
            memset(mark, 
0sizeof(mark));
            
if(dfs(sum/get00)==1)
                
break;
            
else{
                
get--;
                
while(sum%get!=0){
                    
get--;
                }
            }
        }
        printf(
"%d\n",sum/get);
    }
    
return 0;
}