搜索算法(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;
}



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