搜索算法(poj1011)

首先說一下這道題的目的實際就是給出了有限個小木棍的長度,而且所有的棍子都是由有限個長度相同的棍子截斷得到的,讓你求被截棍子的最小長度,本題的算法深搜,當然需要幾個剪枝的:

1、截棍子的最小長度>=小木棍的最大長度;

2、截棍子的長度一定是總長度的分子;

3、搜索時第i-1條木條跟第i(i>0)木條長度相等且沒有被使用,即第i根木棍也不會用;

4、第一根未使用木條放進去都不能爲true,即該長度不對

//
//  main.cpp
//  T1011
//
//  Created by 小哲 on 16/10/3.
//  Copyright © 2016年 小哲. All rights reserved.
//

#include <iostream>
using namespace std;



int length;
bool *IsUsed;
int numArray[64];

bool DFS(int num,int left,int l)
{
    if (num==0&&left==0) {
        return true;
    }
    if (left==0) {
        num--;
        left=l;
    }
    for (int i=0; i<length; i++) {
        if (!IsUsed[i]&&numArray[i]<=left) {
            if (i>0&&numArray[i-1]==numArray[i]&&!IsUsed[i-1]) {
                  continue;//在i-1條木條跟當前i木條長度相等且沒有被使用,即當前這根也不會用
            }
            IsUsed[i]=true;
            if (DFS(num, left-numArray[i], l)) {
                return true;
            }
            IsUsed[i]=false;
            if (left==l||numArray[i]==left) {//left==l說明連第一根木條放進去都不行,即爲錯;numArray[i]==left說明最大的這根放進去不行,那比他小的湊出left長度的放進去也不能成功
                return false;
            }
        }
    }
    return false;
}

void sort(int n)
{
    for (int i=0; i<n; i++) {
        for (int j=n-1; j>=i; j--) {
            if (numArray[i]<numArray[j]) {
                int temp=numArray[i];
                numArray[i]=numArray[j];
                numArray[j]=temp;
            }
        }
    }
}


int main(int argc, const char * argv[]) {
    
    int tempNum;
    cin>>length;
    while (length!=0) {
        IsUsed=new bool[length];
        int sum=0;
        for (int i=0; i<length; i++) {
            cin>>tempNum;
            sum+=tempNum;
            numArray[i]=tempNum;
        }
        sort(length);//先從大到小排序
        for (int i=numArray[0]; i<=sum; i++) {
            if (sum%i==0) {
                for (int j=0; j<length; j++) {
                    IsUsed[j]=false;
                }
                if (DFS(sum/i-1, i, i)) {
                    cout<<i<<endl;
                    break;
                }
            }
        }
        cin>>length;
        
    }
    
    
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章