洛谷p1120小木棍(剪枝优化)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
const int maxn = 200100;

int a[70];
int vis[70];
int n;
int flag;
int len;

bool cmp(int a,int b)
{
    return a>b;
}

void dfs(int num,int nlen,int pos)       //还差几根    当前长度   当前下标
{
    if(num==0){
        flag=1;
        return;
    }
    if(nlen==len) 
    {
        dfs(num-1,0,1);
        return;
    }
    for(int i=pos;i<=n;i++)
    {
        if(!vis[i] && nlen+a[i] <= len)
        {
            vis[i] = 1;
            dfs(num,nlen+a[i],i);
            if(flag) return;
            vis[i] = 0;
            //if(nlen==0) break;
            if(len-nlen==a[i] || nlen==0) break;  // 二
            while(i+1 <= n && a[i+1] == a[i]) i++;  // 三
        }
    }
}

int main()
{
    int sum=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]>50)
        {
            i--;
            n--;
        }
        else sum+=a[i];
    }
    sort(a+1,a+n+1,cmp);
    for(int i=a[1];i<=sum;i++)
    {
        len=i;
        for(int i = 0; i < n; i++) vis[i] = 0;
        if(sum%i==0)             // 一
        dfs(sum/i,0,1);
        if(flag) break;
    }
    printf("%d\n",len);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/chilkings/p/12005191.html