小木棍 爆搜剪枝
Posted santiego
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小木棍 爆搜剪枝相关的知识,希望对你有一定的参考价值。
小木棍 爆搜剪枝
看了题解,用一个桶记录小木棍(很是机智,反正\(N\le50\)),然后就是爆搜剪枝了。
主要是注意一个优化思想:每次拼一个木棍时,一定先用大的去填再用小的去补。
递减遍历桶和下面这个最重要的剪枝都是这个优化思想
if(sum+i==per||sum==0) break;
连用大刚好填满这种最优方法都无法拼出,那更不用说先用小的去拼这种方法了。
#include <cstdio>
#include <cstdlib>
#define MAX(A,B) ((A)>(B)?(A):(B))
#define MIN(A,B) ((A)<(B)?(A):(B))
using namespace std;
int n,cnt[55];
int mx=0,mi=75;
void solve(int num, int sum, int per, int s)
if(num==0)
printf("%d\n", per);
exit(0);
if(sum==per)
solve(num-1, 0, per, mx);
return;
for(register int i=s;i>=mi;--i)
if(cnt[i]==0||i+sum>per) continue;
--cnt[i];
solve(num, sum+i, per, i);
++cnt[i];
if(sum+i==per||sum==0) break;
int temp,all;
int main()
scanf("%d", &n);
for(int i=1;i<=n;++i)
scanf("%d", &temp);
++cnt[temp];
all+=temp;
mx=MAX(mx, temp);
mi=MIN(mi, temp);
for(int i=mx;i<=all/2;++i)
if(all%i!=0) continue;
solve(all/i, 0, i, mx);
printf("%d\n", all);
return 0;
以上是关于小木棍 爆搜剪枝的主要内容,如果未能解决你的问题,请参考以下文章