大體題意:
給你n個木棍,要求分配這個n 個木棍到x組,使得x組的木棍長度和都相同,問最小的長度和是多少?
思路:
直接搜索:
需要加很多剪枝才能過:
1.首先你枚舉時,應(yīng)該枚舉組數(shù),而不是長度和,否則循環(huán)會很長。
2.如果第一個木棍選完了,沒找到合適的使它權(quán)值和為枚舉的答案,就不可能有答案了。
3.如果第i個木棍能組成ans,但其余的不能了,也不能有答案了。
4.當(dāng)長度小于ans時,前面的不用在循環(huán)了,直接從當(dāng)前位置繼續(xù)往后找就好了。
5.if else if 寫成if else 的話,容易漏掉長度和 > ans的情況。。。。坑死了這里。。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 500 + 7;int a[maxn], n, f, g, df;bool vis[maxn];bool cmp(int& a,int& b){ return a > b;}bool dfs(int cur,int c,int pos,int len){ if (cur == f) { if (len == n)return true; return false; } for (int i = pos; i < n; ++i){ if (!vis[i]){ if (c+a[i] == g){ vis[i] = 1; if (dfs(cur+1,0,0,len+1)) return true; vis[i] = 0; return false; while(i+1 < n && a[i+1] == a[i])++i; } else if (c+a[i] < g){ vis[i] = 1; if ( dfs(cur,c+a[i],i+1,len+1) ) return true; vis[i] = 0; while(i+1 < n && a[i+1] == a[i])++i; } if (!pos)return false; } } return false;}int main(){ while (~scanf("%d",&n) && n){ int sum = 0; bool ok = 1; for (int i = 0; i < n; ++i) { scanf("%d",a+i); sum += a[i]; if (i){ if (a[i] != a[i-1])ok = 0; } } if (ok) { PRintf("%d/n",a[0]); continue; } sort(a,a+n,cmp); int ans = sum; for (int i = n - 1; i > 1; --i){ if (sum % i == 0 && sum / i >= a[0]){ f = i; g = sum/i; memset(vis,0,sizeof vis); if (dfs(0,0,0,0)){ ans = g; break; } } } printf("%d/n",ans); } return 0;}/**95 2 1 5 2 1 5 2 141 2 3 40**/
新聞熱點(diǎn)
疑難解答