标签:
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 127727 | Accepted: 29912 |
Description
Input
Output
Sample Input
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
Sample Output
6 5
题意:告诉n个小木条,问能组成几个等长的木棍,并且让长度最小。
分析:神剪枝问题,有与没有天壤之别,
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 100009
using namespace std;
int cmp(int a,int b)
{
return a>b;
}
int sum,mmin;
int flag;
int n;
int vis[N];
int a[N];
int cnt;
int len;
void dfs(int p,int num,int x)
{
if(flag) return;
if(num==cnt)
{
flag=1;
return;
}
if(x==len)
dfs(0,num+1,0);
for(int i=p;i<n;i++)
{
if(vis[i]) continue;
if( (x+a[i])>len) continue;
vis[i]=1;
dfs(i+1,num,x+a[i]);
vis[i]=0;
if(flag) return;
//if(x==0||x+a[i]==len)//神剪枝,有就16毫秒,没有就是TLE
// return;
//具体理解为
if(x==0)//如果第一个木棒都没有添加,说明有问题
return;
if(x+a[i]==len)//如果现在本来应该成功,应该进入递归变为0,却失败,说明有问题
return;
}
}
int main()
{
while(scanf("%d",&n),n)
{
sum=0;
mmin=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
mmin=max(mmin,a[i]);
sum+=a[i];
}
sort(a,a+n,cmp);
memset(vis,0,sizeof vis);
int ans=sum;
for(len=mmin;len<=sum;len++)
{
if(sum%len) continue;
cnt=sum/len;
flag=0;
dfs(0,0,0);
if(flag)
{
ans=len;
break;
}
}
printf("%d\n",ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/wust_zjx/article/details/46773209