当前位置: 代码迷 >> 综合 >> LA 3667 Ruler IDA* .
  详细解决方案

LA 3667 Ruler IDA* .

热度:60   发布时间:2023-09-23 05:04:33.0

题目地址:http://vjudge.net/problem/UVALive-3667

一开始 以为就是DFS搜索,选择题目中给的刻度,一个一个试,最短的的那个就是答案,

而且题目给的刻度是小于等于50的,那很明显可以用二进制压缩

然而 竟然尺子上的刻度不是题目给出的,所以之前枚举都的方法都错了

应该是迭代加深搜索+剪枝

#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b)  for(int i=a;i<=(int)(b);++i)
#define REPD(i,a,b) for(int i=a;i>=(int)(b);--i)
typedef long long LL;
int n,a[50+5],dep,ans[10];
int ID[1000000+5];
bool DFS(int cur,LL done){  //从pos位置开始选if(cur==dep) return done==(1ll<<n)-1;REP(i,1,cur-1){REP(j,1,n-1){if(done&(1ll<<j)) continue;int m=ans[i]+a[j];if(m<=ans[cur-1]||m>=a[n]) continue;LL nd=done;ans[cur]=m;REP(k,1,cur-1) {m=ans[cur]-ans[k];if(ID[m]) nd|=(1ll<<ID[m]);}m=a[n]-ans[cur];if(ID[m]) nd|=(1ll<<ID[m]);if(DFS(cur+1,nd)) return true;}}return false;
}
int main(int argc, char const *argv[])
{int kase=0;while(scanf("%d",&n)==1&&n){REP(i,1,n) scanf("%d",&a[i]);sort(a+1,a+1+n); n=unique(a+1,a+1+n)-a-1;memset(ID,0,sizeof(ID));REP(i,1,n) ID[a[i]]=i;dep=2; ans[1]=0;while(dep*(dep-1)/2<n) dep++;while(!DFS(2,1)) dep++;printf("Case %d:\n%d\n0", ++kase,dep);ans[dep]=a[n];   //最后一个肯定是a[n];REP(i,2,dep) printf(" %d", ans[i]);printf("\n");}return 0;
}