标签:
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