LA 3667 Ruler IDA* .

题目地址: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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值