您的位置:首页 > 其它

UVALive 3667 dfs

2017-03-08 14:00 399 查看
题目的数据量一看就是暴力的解法,直接深搜模拟一下题目的过程就可以了,具体做法可以看看下面的代码。由于忘记把初始输入的数据排序WA了好多次。查错的时候发现一组数据:

9 3 6 10 12 14 16 19 24 26

正确答案应该是

6

0 14 24 26 30 33

而网上的一些AC代码的结果都是

7

0 3 6 10 22 24 26

问题在于题目中的两个约束条件:刻度尽量少和尺子长度尽量短之间的优先级关系,题目里没有明确说清楚。有些代码剪枝时认为“如果超过最大的尺度那么这个解就是不合格的”。但是根据题目意思,应该是M先要保证最小,然后再是ans[M-1]尽量小。不过题目数据比较水,两种都能ac通过。

再提供几个测试数据:

4 1 3 7 11

11 1 2 3 4 5 6 7 8 9 10 11

0

Case 1:

4

0 1 4 11

Case 2:

6

0 1 2 3 7 11

#include<stdio.h>
#include<string.h>
#include<algorithm>
int s[55],depth,vis[55],N,z[10];//z[]表示选中的数
bool sel[1000010];
bool dfs(int bz,int x){
//  printf("   - dfs(%d,%d)\n",bz,x);
if(x==depth){
//  printf(" -> ");
//  for(int i=0;i<x;i++)printf("%d ",z[i]);
//  printf("%d\n",s
);
for(int i=1;i<N;i++)if(!vis[i]){
bool flag=false;
for(int j=0;j<x;j++){
if(sel[z[j]+s[i]]){
flag=true;break;};
}
if(!flag){
//          printf("<= %d([%d])\n",s[i],i);
return false;
}
}
return true;
}else{
for(int i=bz;i<N;i++)if(!vis[i]){
int t;
for(int j=0;j<x;j++)if(!sel[t=z[j]+s[i]]){
vis[i]=1;
z[x]=t;
sel[t]=1;
if(dfs(i+1,x+1))return true;
sel[t]=0;
vis[i]=0;
}
}
}
return false;
}
int main(){
int cas=1;
//  freopen("1.in","r",stdin);
//  freopen("1.txt","w",stdout);
while(~scanf("%d",&N),N){
for(int i=1;i<=N;i++) scanf("%d",s+i);
std::sort(s+1,s+N+1);
sel[s
]=1;
for(depth=1;depth<=6;depth++){
if(dfs(1,1)){
z[depth]=s
;
std::sort(z+1,z+depth+1);
printf("Case %d:\n%d\n0",cas++,depth+1);
for(int i=1;i<=depth;i++)printf(" %d",z[i]);
printf("\n",s
);
break;
}
}
memset(vis,0,sizeof(vis));
memset(sel,0,sizeof(sel));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dfs acm