uva307 dfs

把博客當作一個記錄代碼的地方吧。這個題想一想還真的挺不錯的,能提高對回溯法的理解。題意不難理解,一堆切開的小木棒,然後把這些小木棒合起來,找到這些合起來的小木棒的最小長度,最關鍵的一點這些小木棒合起來的長度都是一樣的。

我開始的思路試枚舉多少根小木棒,然後通過總的除以根數就得到了小木棒的長度,然後一一去判斷,結果寫着寫着怎麼也不會寫了,就從網上借鑑了大神們的代碼。思路:直接枚舉長度,然後通過遞歸求根數然後判斷相乘之後能否等於總長度即可,這裏要注意的就是枚舉的長度一定要大於等於木棒的最大長度,小於等於總長度。網上的大神貌似都用到了剪枝,但我覺得剪不剪都一樣(可能是自己太弱了,看不出區別)所以就沒有用到剪枝。不多說,上代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxed=100+10;
int panDuan[maxed],n,muBang[maxed],changDu,zong;
int main()
{
    bool slove(int,int,int);
    bool cmp(int,int);
    while(scanf("%d",&n)!=EOF&&n){
        //memset(panDuan,0,sizeof(panDuan));
        memset(muBang,0,sizeof(muBang));
        int t;
        zong=0;
        for(int i=0;i<n;i++){
            scanf("%d",&t);
            muBang[i]=t;
            zong+=t;
        }
        sort(muBang,muBang+n,cmp);//對木棒長度進行排序,這樣每次都從最大的開始找,會節省很多時間。
        for(changDu=muBang[0];changDu<=zong;changDu++)
            if(!(zong%changDu)){
                //cout<<2<<endl;
                memset(panDuan,0,sizeof(panDuan));
                if(slove(0,0,0))
                    break;
            }
        printf("%d\n",changDu);
    }
    return 0;
}
bool cmp(int x,int y)
{
    return x>y;
}
bool slove(int now,int geShu,int cur)//now當前長度,geShu當前的木棒根數,cur當前枚舉到的位置(這裏一定要寫位置,如果每次都從0開始枚舉會出現時間溢出)
{
    //cout<<1<<endl;
    if(geShu*changDu==zong)
        return true;
    for(int i=cur;i<n;i++){
        if(panDuan[i])
            continue;
//        if(i&&!panDuan[i-1]&&muBang[i]==muBang[i-1])
//            continue;
        if(now+muBang[i]==changDu){
            panDuan[i]=1;
            if(slove(0,geShu+1,0))
                return true;
            panDuan[i]=0;
            return false;
        }
        else if(now+muBang[i]<changDu){
            panDuan[i]=1;
            if(slove(now+muBang[i],geShu,i+1))
                return true;
            panDuan[i]=0;
            if(now==0)
                return false;
        }
    }
    return false;
}

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