UVALive 3667 dfs

    xiaoxiao2021-03-25  152

    题目的数据量一看就是暴力的解法,直接深搜模拟一下题目的过程就可以了,具体做法可以看看下面的代码。由于忘记把初始输入的数据排序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[N]); 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[N]]=1; for(depth=1;depth<=6;depth++){ if(dfs(1,1)){ z[depth]=s[N]; 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[N]); break; } } memset(vis,0,sizeof(vis)); memset(sel,0,sizeof(sel)); } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-2268.html

    最新回复(0)