题目:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200820225234642.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjcyMTQxMg==,size_16,color_FFFFFF,t_70#pic_center)
分析:二分和树都比较简单,本来想着再水一波简单的,但是搜搜题好像都有一定的难度。
直接看的答案。
首先思考不能二分。因为答案不满足特点。(可以意会)
1.题目缺陷:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200820225428328.png#pic_center)
2.要求的是原始木棍的最小可能长度,那么我枚举开始答案是木棍现长的最大值。然后不断加最小的。
3.在判断一个答案是否符合要求的时候,应该:优先使用长的木棍。
4.在判断一个答案是否符合要求的时候,首先应该整除总长度。
嗯,可以写代码了。
代码:我咋感觉不用搜索呢!用的 ,。
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > vv;
int m;
vector<int> v;
int maxx=-1;
int done[100];
int sum_len=0;
void f(int k,int rest,int goal,int sum_len)
{
if(k*goal==sum_len) {
cout<<goal;
exit(0);
}
if(rest==0) f(k+1,goal,goal,sum_len);
int last=-1;
for(int i=v.size()-1;i>=0;i--)
{
if(done[i]==1) continue;
if(last==-1) last=i;
else if(v[last]==v[i]) continue;
if(v[i]<=rest)
{
done[i]=1;
f(k,rest-v[i],goal,sum_len);
done[i]=0;
}
}
}
int main()
{
cin>>m;
for(int i=0;i<m;i++)
{
int c; cin>>c;
if(c<=50)
{
v.push_back(c);
maxx=max(maxx,c);
sum_len+=c;
}
}
for(int i=maxx;;i++)
{
if(sum_len%i!=0) continue;
memset(done,0,sizeof(done));
f(1,i,i,sum_len);
}
}
结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/202008211043210.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjcyMTQxMg==,size_16,color_FFFFFF,t_70#pic_center)
修改粗心导致的忘记排序,以及忘记修改last:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200821104816207.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjcyMTQxMg==,size_16,color_FFFFFF,t_70#pic_center)
去掉多余的memset:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200821110335220.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjcyMTQxMg==,size_16,color_FFFFFF,t_70#pic_center)
我感觉你说的优化我都用了,还t?先放弃了:
#include<bits/stdc++.h>
using namespace std;
vector<vector<int> > vv;
int m;
vector<int> v;
int maxx=-1;
int done[100];
int sum_len=0;
void f(int k,int rest,int goal,int sum_len)
{
if(k*goal==sum_len) {
cout<<goal;
exit(0);
}
if(rest==0) f(k+1,goal,goal,sum_len);
int last=-1;
for(int i=v.size()-1;i>=0;i--)
{
if(done[i]==1) continue;
if(last==-1) last=i;
else if(v[last]==v[i]) continue;
last=i;
if(v[i]<=rest)
{
done[i]=1;
f(k,rest-v[i],goal,sum_len);
done[i]=0;
}
}
}
int main()
{
cin>>m;
for(int i=0;i<m;i++)
{
int c; cin>>c;
if(c<=50)
{
v.push_back(c);
maxx=max(maxx,c);
sum_len+=c;
}
}
sort(v.begin(),v.end());
for(int i=maxx;;i++)
{
if(sum_len%i!=0) continue;
memset(done,0,sizeof(done));
f(1,i,i,sum_len);
}
}