poj1011 Sticks DFS+回溯

來源:互聯網
上載者:User

標籤:dfs

轉載請註明出處:http://blog.csdn.net/u012860063

題目連結:http://poj.org/problem?id=1011

Description

George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

Input

The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.

Output

The output should contains the smallest possible length of original sticks, one per line.

Sample Input

95 2 1 5 2 1 5 2 141 2 3 40

Sample Output

65

Source

Central Europe 1995

題目的大意:是給了你有限個棍子以及每個棍子的長度,而且所有的棍子都是由有限個長度相同的棍子截斷得到的,讓你求被截棍子的最小長度,本題的演算法是深搜,當然需要幾個剪枝的!

代碼如下:

#include <iostream>#include <algorithm>using namespace std;int sticks[65];int used[65];int n,len;bool dfs(int i,int l,int t)//i為當前試取的棍子序號,l為要拼成一根完整的棍子還需要的長度,t初值為所有棍子總長度 {    if(l==0)    {        t -= len;//如果len為所有棍子的和        if(t == 0)return true;               for(i = 0; used[i]; i++);            //剪枝1:搜尋下一根大棍子的時候,找到第一個還沒有使用的小棍子開始        used[i]=1;                           //由於排序過,找到的第一根肯定最長,也肯定要使用,所以從下一根開始搜尋        if(dfs(i+1,len-sticks[i],t))return true;        used[i]=0;//回溯        t+=len;    }    else    {        for(int j = i; j < n; j++)        {            if(j>0 && (sticks[j]==sticks[j-1]&&!used[j-1]))  //剪枝2:前後兩根長度相等時,如果前面那根沒被使用,也就是由前面那根                continue;                                                //開始搜尋不到正確結果,那麼再從這根開始也肯定搜尋不出正確結果,此剪枝威力較大            if(!used[j] && l>=sticks[j])   //剪枝3:最簡單的剪枝,要拼成一根大棍子還需要的長度L>=當前小棍子長度,才能選用                                       {                l-=sticks[j];                used[j]=1;                if(dfs(j,l,t))return true;                l+=sticks[j];//回溯                used[j]=0;                                if(sticks[j]==l)    //剪枝4:威力巨大的剪枝,程式要運行到此處說明往下的搜尋失敗,若本次的小棍長度剛好填滿剩下長度,但是後                    break;           //面的搜尋失敗,則應該返回上一層            }        }    }    return false;}bool cmp(const int a, const int b){     return a>b; }int main(){    while(cin>>n&&n)    {        int sum=0;int max = -1;        for(int i = 0; i < n; i++)        {            cin>>sticks[i];            sum += sticks[i];            used[i] = 0;if(sticks[i] > max)//找出最長的棍子max = sticks[i];        }                sort(sticks,sticks+n,cmp);   //剪枝5:從大到小排序後可大大減少遞迴次數                bool flag=false;        for(len = max; len <= sum/2; len++)   //剪枝6:大棍長度一定是所有小棍長度之和的因數,且最小因數應該不小於小棍中最長的長度        {            if(sum%len == 0)                 {                if(dfs(0,len,sum))                {                    flag=true;                    cout<<len<<endl;                    break;                }            }        }        if(!flag)            cout<<sum<<endl;    }    return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.