Sticks
题目传送门。
题目大意是,给你一个数字n代表总共的棍子数量,要做的就是,把这几根棍子拼成长度相同的棍子,并且让所拼成的棍子的长度尽可能地小,也就是拼成的棍子的数量尽可能的多。
在这里很简单的想到要给棍子排一下序,这样可以更简单找到合适棍子的。
-------------------下面的代码除去注释就是我自己写的代码。----------------------
#include<iostream>
#include<cstring>
#include<algorithm>
const int maxn=70;
int a[maxn],visit[maxn];
int n,total,target;
using namespace std;
bool dfs(int sum,int len,int pos) {if(sum==total) return true;if(len==target) return dfs(sum+1,0,0);for(int i=pos;i<n;i++) {if(!visit[i]&&len+a[i]<=target) {visit[i]=1;if(dfs(sum,len+a[i],i+1)) return true;visit[i]=0;
// if(len==0) return false;
// while(i+1<n&&a[i+1]==a[i]) i++;}}return false;
}
int main()
{freopen("D:\\MY\\ce.txt","r",stdin);while(cin>>n&&n) {int sum=0,ans=0;memset(a,0,sizeof(a));memset(visit,0,sizeof(visit));for(int i=0;i<n;i++) {cin>>a[i];sum+=a[i];}sort(a,a+n,greater<int>());for(int i=a[0];i<=sum;i++) {if(sum%i==0) {total=sum/i;target=i;if(dfs(0,0,0)) {ans=i;break;}}}cout<<ans<<endl;}return 0;
}
这段注释就是这个代码的灵魂所在,
没有这一段能在样例中跑出超时,
但是有这一段代码轻轻松松就跑完了所有样例。
但是这个代码的精髓就是:
第一步if剪枝:
会进入当len==0的时候这里就代表着,有一根棍子找了一圈发现找不到满足条件的,然后回到main函数里的for循环,尝试下一个target。
第二步while剪枝:
单现在查找的target有可能时正确答案时,对len不为0的情况,就是当前尝试的棍子不符合条件,所以当前长度的棍子可以不用再试了,换别的棍子继续尝试。