bjfu1014 古怪的实验

    xiaoxiao2026-04-15  2

    古怪的实验

    时间限制(C/C++):1000MS/3000MS          运行内存限制:65536KByte 总提交:233            测试通过:43

    描述

    Ben 喜欢做各种古怪的实验。这次他拿来一组等长的木棒,将它们随机地裁断,使得每一节木棒的长度都不超过50 个长度单位。然后他又想把这些木棒恢复到裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助他计算木棒的可能最小长度。每一节木棒的长度都用大于零的整数表示。

    输入

    输入包含多组测试数据,每组测试数据包括两行。第一行是一个不超过64 的整数N,表示裁截之后共有多少节木棒,当N为0时表示输入结束,不做任何处理。第二行是经过裁截后,所得到的各节木棒的长度。

    输出

    对于每组测试数据,请输出木棒的可能最小长度,每组输出占一行。

    样例输入

    9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0

    样例输出

    6 5

    题目来源

    ben

    解题思路:dfs+剪枝

        木棒匹配首先应从最长的一段木棒开始匹配,因此首先要对木棒进行由大到小的排序     剪枝: 1.所选的木棒没有使用过 2.匹配过程如果不成功记录下该木棒的长度,下次匹配如果遇到此长度的木棒跳过 3.当前匹配的木棒长度一定小于总长度除以段数 4.如果第一段木棒没有匹配成功,则匹配失败

    5.如果匹配到最后一根没有成功,匹配失败

    AC代码:

    #include<iostream> #include<algorithm> #include<functional> using namespace std; int a[64],v[64],n,l; bool pin(int length,int i=0,int j=0,int action=0,int clength=0){ if(i==n) return true; else{ if(clength==length) return pin(length,i+1,i+2,0,0); if(action==0){ if(v[i]) return pin(length,i+1,i+2,0,0); else{ v[i]=1; if(pin(length,i,i+1,1,a[i])) return true; v[i]=0; return false; } } else{ while(j<n){ if(a[j]*(n-j)+clength<length) break; if(a[j]+clength>length){ j++; continue; } if(!v[j]){ v[j]=1; if(pin(length,i,j+1,1,clength+a[j])) return true; v[j]=0; j++; while(j<n&&a[j]==a[j-1]) j++; } else j++; } return false; } } } int main(){ while(scanf("%d",&n)!=EOF&&n){ l=0; for(int i=0;i<n;i++){ scanf("%d",&a[i]); l+=a[i]; } sort(a,a+n,greater<int>()); for(int i=n;i>0;i--) if(l%i==0&&l/i>=a[0]){ memset(v,0,sizeof(v)); if(pin(l/i)){ printf("%d\n",l/i); break; } } } return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1308856.html
    最新回复(0)