[Explanations] small wooden sticks-- Los Valley 1120

Original title chain

Submission: AC

The main algorithm:

This is a classic wide search questions, mainly on the pruning . Now each of the sticks enter and cut in accordance with descending order (1 prune);

Then stick the maximum value from the start of the enumeration (pruning 2), has been to enumerate the total length of all the wooden sticks, wooden poles as these are to be spliced, only the results after the maximum length possible.

Next, we consider whether it is reasonable so divided: if the total length divided by the original enumeration does not cut the length not divisible, it is clear that is not going to work (pruning 3).

After deep search began, the number of sticks root if the current mosaic stick than we used to be more pre-enumeration, proved to be the do the same (because it proves that one can be successful before cnt stitching)

Ps: (cnt of the number enumerated previously used wooden stick stitching each) (4 pruning). If the length of the current mosaic sticks of equal length to show that pre-enumeration of the stick stitching successful, the next splice into the stick. Pruning and other codes are explained in the Notes program, Comparison, easy to understand.

Source

#include <bits/stdc++.h>
using namespace std;
int len,cnt,n,a[1010];
bool vis[1010];
inline bool dfs(int stick,int cab,int last){
/*
    last:代表当前从那根木棍继续拼接
    cab:代表当前正在拼的木棍的长度
    stick:代表已经拼接好的木棍由几根木棍组成 
*/
    if(stick > cnt)return true;//上一次递归已经成功拼接了cnt跟木棍,这次直接return 
    if(cab == len)return dfs(stick + 1,0,1);//当前拼接的木棍满足要求,继续拼接下一个木棍 
    int fail = -1;
    for(int i = last;i <= n;i++){
        if(!vis[i] && cab + a[i] <= len && fail != a[i]){
            vis[i] = true;
            if(dfs(stick,cab + a[i],i + 1))return true;
            vis[i] = false;fail = a[i];
            if(cab == 0 || cab + a[i] == len)return false;
        }
    }
    return false;
}
inline bool cmp(int x,int y){
    return x > y; 
}
int main(){
    while(cin>>n){
        if(n == 0)return 0;
        memset(vis,false,sizeof(vis));
        int maxx = -1,sum = 0;
        for(int i = 1;i <= n;i++){
            cin>>a[i];
            if(a[i] > 50){i--;n--;continue;}
            sum += a[i];
            maxx = max(maxx,a[i]);
        }
        sort(a + 1,a + n + 1,cmp);
        for(len = maxx;len <= sum;len++){//len:枚举切割之前每根完整木棍的长度 
            if(sum % len)continue;
            cnt = sum / len;//cnt代表当前枚举的木棍长度应该由cnt根木棍组成 
            if(dfs(1,0,1))break;
        }
        cout<<len<<endl;
    }
    return 0;
} 

Guess you like

Origin www.cnblogs.com/czy--blog/p/11741750.html