Uva 307 Sticks(IDA*)

来源:互联网 发布:y系列6及电机数据大全 编辑:程序博客网 时间:2024/05/19 07:08

这道题题意还是好理解就不多说了,,详见紫书P218。

应该属于比较明显的IDA*了, 枚举原始木棍的长度, 从max a[i]开始,如果同时总长度mod当前长度不为0也跳过, 比较基础的剪枝。另外一个比较重要的剪枝是, 先把小木棍降序排序, 从大往小拼, 凑木棍的时候,如果用到了长度为d的木棍,那么接下来就只用枚举长度<=d的木棍,因为>d的木棍已枚举过了。

#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <string>#include <cctype>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <sstream>#include <iostream>#include <algorithm>using namespace std;#define ls id<<1,l,mid#define rs id<<1|1,mid+1,r#define OFF(x) memset(x,-1,sizeof x)#define CLR(x) memset(x,0,sizeof x)#define MEM(x) memset(x,0x3f,sizeof x)typedef long long ll ;typedef pair<int,int> pii ;const int maxn = 1e4+50 ;const int inf = 0x3f3f3f3f ;const int MOD = 1e9+7 ;int stick;int num[55],Num[55],Max;int n,total,ans,maxd;int len,last,cnt=0;bool dfs(int cur,int step,int last) {    if (step==len) return 1;    for (int i=last;i;i--) {        if (i+cur>maxd||!num[i]) continue ;        num[i]--;//        if (maxd==73&&cnt++<250) cout << step << endl ;        if (i+cur==maxd) {            if (dfs(0,step+1,Max)) return 1;            num[i]++;            return 0;        }        if (dfs(cur+i,step,i)) return 1;        num[i]++;        if (cur==0) return 0;    }    return 0;}int main () {#ifdef LOCAL    freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);//      freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);#endif    while (cin >> n && n ) {        Max=0;        total=0;        CLR(Num);        for (int i=0;i<n;i++) {            scanf("%d",&stick);            Num[stick]++;// 用num来存每个长度的小木棍的数量, 这样枚举就只用从50到1, 似乎可以省点时间Orz            Max=max(stick,Max);            total+=stick;        }        for (maxd=Max;maxd<total;maxd++) {            if (total%maxd) continue ;            memcpy(num,Num,sizeof Num);            len=total/maxd;//            cout << len << endl ;            if (dfs(0,0,Max)) break;        }        cout << maxd << endl ;    }    return 0;}


0 0
原创粉丝点击