UVA 307(p218)----Sticks

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const int maxn=1e7;
int n,l,sum;
int a[maxn];
int v[maxn];
int cmp(int a,int b)
{
    return a>b;
}
int dfs(int len,int num,int pos)
{
    if(l*num==sum) return 1;
    for(int i=pos; i<n; i++)
    {
        if(v[i]||(i&&!v[i-1]&&a[i-1]==a[i])) continue;
        if(len+a[i]==l)
        {
            v[i]=true;
            if(dfs(0,num+1,0)) return 1;
            v[i]=false;
            return 0;
        }
        else if(len+a[i]<l)
        {
            v[i]=true;
            if(dfs(len+a[i],num,i+1)) return 1;
            v[i]=false;
            if(!len) return 0;
        }
    }
    return 0;
}
void solve()
{
    int flag=0;
    for(l=a[0]; l<=sum/2; l++)
    {
        if(sum%l) continue;
        memset(v,0,sizeof(v));
        if(dfs(0,0,0))
        {
            flag=1;
            break;
        }
    }
    if(flag)
        printf("%d\n",l);
    else printf("%d\n",sum);
}
int main()
{
#ifdef debug
    freopen("in.in","r",stdin);
#endif
    while(scanf("%d",&n)==1&&n)
    {
        sum=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        sort(a,a+n,cmp);
        solve();
    }
    return 0;
}

题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=243

题解:

1.将木棒从大到小排序,优先使用大的木棒,加快组合速度。

2.木棒长度介于max到sum/2之间。

3.原木棒长度为sum约数。

4.对于第i根木棒,若a[i]==a[i-1]且第i-1根木棒未被选上,则第i根同样不会被选上。

5.若当前在拼接第i根木棒的第一段,若使用剩余可使用最长木棒拼接失败,则退出搜索(当元素多时不符合要求,元素减少时一定不符合)。


你可能感兴趣的:(UVA 307(p218)----Sticks)