POJ 1011 木棒

原创 2016年08月30日 23:44:12

木棒
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 138745 Accepted: 32693

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

Input
输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。

Output
为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

Sample Input

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

Sample Output

6
5


第二次做这题了 上学期做了一次 再做还是不会..翻回以前代码才过了
刚开始穷举每一种木棒组合 然后dfs验证这个长度
坑爹啊..枚举了2^n种情况
原本的木棒可能长度len只在 max(a1,a2,...,an)<=len<=a1+a2+...+an<=50*n范围内
完全可以穷举长度
加上各种剪枝 终于过了

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<time.h>
#include<math.h>
#include<list>
#include<cstring>
#include<fstream>
//#include<memory.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define INF 1000000007
#define pll pair<ll,ll>
#define pid pair<int,double>

#define sci(a) scanf("%d",&a)
#define scll(a) scanf("%lld",&a)
#define scd(a) scanf("%lf",&a)
#define scs(a) scanf("%s",a)
#define pri(a) printf("%d\n",a)
#define prll(a) printf("%lld\n",a)
#define prd4(a) printf("%.4lf\n",a)
#define prd(a) printf("%lf\n",a)
#define prs(a) printf("%s\n",a)
//#define CHECK_TIME

int len[65],n;
bool used[65];

bool dfs(int uses,int nowlen,int LEN){
/*uses用了多少根木棒 
nowlen当前组合出来的长度 
LEN要恢复成的长度*/
    if(uses==n)
        return nowlen==LEN;
    if(nowlen==LEN){//如果长度已经组合出LEN 将nowlen设为0 继续找
        int st=0;
        while(used[st])//每一根木棒都要被用掉 所以直接选择一根没用过的 
            ++st;
        used[st]=true;
        bool res=dfs(uses+1,len[st],LEN);//用st木棒
        used[st]=false;
        return res;
    }
    for(int i=1;i<n;++i){
        if(used[i])//用过了
            continue;
/*如果len[i]==len[i-1] 选择了len[i-1]时不选len[i]的情况 和 现在的情况(len[i]选了 len[i-1]不选)等价 所以没必要再重复检查*/
        if(len[i]==len[i-1]&&used[i-1]==false)
            continue;
        if(len[i]+nowlen<=LEN){//组合起来长度不超过LEN
            used[i]=true;
            if(dfs(uses+1,nowlen+len[i],LEN))
                return true;
            used[i]=false;
        }
    }
    return false;
}

int work(){
    int MAX=0;
    sort(len,len+n,greater<int>());
    fill(used,used+n,false);
    used[0]=true;//第0根木棒一定要被用掉 直接用了它
    for(int i=0;i<n;++i)//计算总长度
        MAX+=len[i];
    for(int i=len[0];i<=MAX;++i)//木棒长度在len[0]到MAX之间
        if(MAX%i==0&&dfs(1,len[0],i))//如果i不能被MAX整除 肯定不能恢复
            return i;
}

int main()
{
    //freopen("/home/lu/文档/r.txt","r",stdin);
    //freopen("/home/lu/文档/w.txt","w",stdout);
#ifdef CHECK_TIME
    time_t now=clock();
#endif

    while(sci(n),n){
        for(int i=0;i<n;++i)
            sci(len[i]);
        pri(work());
    }

#ifdef CHECK_TIME
    cout<<"cost time:"
       <<(double)(clock()-now)/CLOCKS_PER_SEC*1000
      <<"ms"<<endl;
#endif
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

木棒拼接 poj1011 搜索+剪枝 递归实现

木棒拼接,POJ上的1011题目:http://poj.org/problem?id=1011         经典的搜索+剪枝问题。这题我已经做第三遍了,感觉依旧很晕。说一下,自己对搜索的感觉。以前...

解题报告 poj 1011 木棒

解题报告 poj 1011 木棒   1.        题目 poj 1011 Description 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50...

poj1011木棒 dfs

木棒 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 143464   Accepted:...

poj1011-Sticks dfs各种剪枝

Sticks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 133058   Accepted: 31236 ...

POJ 1011 木棒问题

•问题描述:             乔治拿来一组等长的棍子,将它们随机地裁断(截断后的小段称为木棒),使得每一节木棒的长度都不超过50个长度单位。然后他又想把这些木棒恢复到为裁截前的状态,...
  • YDYKL
  • YDYKL
  • 2011-07-25 20:28
  • 760

POJ1011 木棒

POJ 1011 stick木棒

POJ1011 木棒

搜索+剪枝

poj1011 木棒 dfs+剪枝

目描述 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮...

POJ1011-Sticks

Poj Sticks(木棒) DFS+剪枝

描述 乔治拿来一组等长的木棒,将它们随机地裁断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)