Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 103596 | Accepted: 23602 |
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
====================================================
这个题目就是深度优先搜索了.之前尝试过把每根棍子安排到1-n节组合棍子上,在中间可以稍微剪枝.无奈超时(后边才发现超得还不是一点点)
然后再一个棍子一个棍子地组合,这样能剪的地方就变多了.
1.最后一节棍子是不用组装的.能组合到第n-1节棍子就ok了(其实对性能貌似没影响)
2.组装每一节棍子用的第一节短棍子不行地话,那就可以判定这个方案是不靠谱的了
3.组装同一节棍子的时候,用的下一节短棍限制到上一节短棍所在的序号后边
4.记录一下当前短棍的长度,下一次尝试就跳过与当前短棍长度相同的棍子
5.棍子从大到小排序.先用大的,再用小的.这样相同的棍子也能在一起了.
以上几点保证了,勉强能过了.测试了两次.一次32MS,一次16MS.估计服务器不稳定把.但是看到那些0MS+4k的答案..应该还有蛮多可以优化的地方.
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool check(vector<int> &x,vector<bool> &y,int l,int n,int c=0,int dep=0,int left=0) //left 搜索起点
{
if(dep == n-1) return true;
int old = -1;
for(unsigned int i = left;i < y.size();++i)
{
int v = x[i];
if(y[i] || v==old || c+v>l) continue;
old = v; y[i] = true;
if(c+v==l)
{
if(check(x,y,l,n,0,dep+1,0)) return true;
}
else
{
if(check(x,y,l,n,c+v,dep,i+1)) return true;
}
y[i] = false;
if(c == 0 || c+v==l) return false;
}
return false;
}
void solve(vector<int> &x,int mmax,int sum)
{
for(int l = mmax;l<=sum;++l)
{
if(!(sum%l))
{
int n = sum/l; //n根
vector<bool> y(x.size(),false);
if(check(x,y,l,n))
{
cout<<l<<endl;
return;
}
}
}
}
int main()
{
freopen("1011.data","r",stdin);
int n;
while(cin>>n,n)
{
vector<int> v; v.reserve(64);
int mmax = -1,sum = 0;
while(n--)
{
int x;
cin>>x;
v.push_back(x);
mmax = max(x,mmax);
sum += x;
}
sort(v.rbegin(),v.rend());
solve(v,mmax,sum);
};
return 0;
}
附测试数据一组:
64
33 36 7 45 6 14 14 14 28 39 35 36 5 33 21 32 29 37 31 3 2 19 40 34 25 1 33 49 20 14 25 36 45 37 47 28 39 8 36 44 8 48 41 1 13 18 9 10 34 42 41 39 42 20 23 6 40 28 49 16 38 33 15 7
0
答案:81