洛谷[P1120 小木棍]
题目:
思路:
枚举小木棒可能的长度,从数组最大值开始枚举,这个值能被总长度整除才是可行的
在使用dfs枚举小木棒的每一种可能,如果不可能就找下一个可能的长度开始枚举
注意不可能的情况就直接剪枝,不然会超时
代码:
#include<bits/stdc++.h>
using namespace std;
int arr[100];
int Len=0;
int BK[100]={0};//木棍状态
int len_club, cnt;
// 目标长度 根数 上次循环 当前长度 当前根数
bool dfs(int mark,int ans,int cont){
if(ans==len_club){
return dfs(1,0,cont+1);
}
if(cont==cnt){
return true;
}
for(int i=mark;i<=Len;i++){
if(BK[i]==0&&arr[i]+ans<=len_club){
BK[i]=1;
if(dfs(i+1,ans+arr[i],cont)) return true;
BK[i]=0;
if(ans==0||ans+arr[i]==len_club)//当前方案能够符合当前根数,但是后面的就拼不了了,拆前面的
return false;
while(arr[i]==arr[i+1])//arr[i]不符合 arr[i+1]一定不符合
i++;
}
}
return false;
}
bool Max(int a,int b){
return a>b;
}
int main(){
int sum=0;
scanf("%d",&Len);
for(int i=1;i<=Len;i++){
scanf("%d",&arr[i]);
sum+=arr[i];
}
sort(arr+1,arr+Len+1,Max);//从大到小排序
for(int i=arr[1];i<=sum;i++){
//枚举每跟的长度
while(sum%i!=0) ++i;
int cont=sum/i;//长度为i的木棍的根数
len_club=i,cnt=cont;
if(dfs(1,0,0)){//如果能合成cont根长度为i的木棍,就直接跳出
printf("%d",i);
break;
}
}
return 0;
}