标签:nyoj 293
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
6 5
#include <cstdio>
#include <algorithm>
using std::sort;
int stick[66], n, sum, len, ok, temp;
bool vis[66];
bool cmp(int a, int b){
return a > b;
}
bool DFS(int k, int left, int total){ //第k个木棍,剩下的匹配长度,剩下的总长度
if(left == 0){ //已经匹配完一份
total -= len;
if(!total) return true;
int i = 1;
while(vis[i]) ++i;
vis[i] = 1; //cut, 找到的第一根肯定要用,此时就给他用掉,如果不用会TLE
if(DFS(i + 1, len - stick[i], total)) return true;
vis[i] = 0;
return false;
}
for(int i = k; i < n; ++i){
if(i > 0 && stick[i] == stick[i-1] && !vis[i-1]) //cut,若前一个相同长度的匹配失效,则当前不需要深搜下去
continue;
if(!vis[i] && left >= stick[i]){
vis[i] = 1; left -= stick[i];
if(DFS(i + 1, left, total)) return true;
vis[i] = 0;
if(!left) return false; //cut
left += stick[i];
}
}
return false;
}
int main(){
while(scanf("%d", &n), n){
sum = ok = 0;
for(int i = 0; i < n; ++i){
scanf("%d", stick + i);
vis[i] = 0; sum += stick[i];
}
sort(stick, stick + n, cmp);
temp = sum / 2; len = stick[0]; //剪枝1
vis[0] = 1;
while(len <= temp){
if(sum % len == 0 && DFS(1, len - stick[0], sum)){ //剪枝2
printf("%d\n", len);
ok = 1; break;
}
++len;
}
if(!ok) printf("%d\n", sum);
}
return 0;
}NYOJ 293 Sticks 【深搜】+【剪枝】,布布扣,bubuko.com
标签:nyoj 293
原文地址:http://blog.csdn.net/chang_mu/article/details/30766491