zoukankan      html  css  js  c++  java
  • poj 1011 DFS+剪枝

    Sticks

    Time Limit: 1000MS
    Memory Limit: 10000K

    Total Submissions: 93302
    Accepted: 20906

    Description

    George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.

    Input

    The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the file contains zero.

    Output

    The output should contains the smallest possible length of original sticks, one per line.

    Sample Input

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

    Sample Output

    6
    5

    这个问题几个剪枝条件都非常关键 不然就会TLE。自己腐朽的脑子不够用,在网上找了一些剪枝的条件。

    题目大意:给出一些长度不大于 50 的木棍, 要求你把这些小木棍拼成 长度相同木棍,当然长度越小越好

    剪枝技巧:

    1. 将输入的木棍长度从大到小排列。直白地说,原因是匹配时用一支长度为K的木棍比用几个短的小木棍拼成的要好。因为短木棍有更高的灵活性,在接下来的匹配中可能发挥更加重要的作用。举个例子,那题目中的第一种输入来说,如果我在匹配时将2,2,1,1用作一组匹配,那么就无法构造出最短长度为6的解。
    2. 开始搜索一支长度为K的木棍时,总是从当前最长的未使用木棍开始,如果搜索匹配不成功的话,那么其他的方法肯定也不能成功。因为每一个木棍都必须被用到。这个剪枝条件如果不用就会TLE。
    3. 相同长度的木棍避免多次搜索。这个剪枝如果不用倒不会造成TLE。
       1: //#define DEBUG
       2: #include <iostream>
       3: #include <cstdio>
       4: #include <cstring>
       5: #include <cstdlib>
       6: //#include <windows.h>
       7: int n;
       8: int stnum;
       9: int segment[70];
      10: int visit[70];
      11: int maxv;
      12: bool flag;
      13: using namespace std;
      14: int Compare(const void *elem1, const void *elem2)
      15: {
      16:     return -*((int *)(elem1)) + *((int *)(elem2));          //降序排序
      17: }
      18: bool dfs(int sticknumber, int curlen, int pos,int sticklen )
      19: {
      20:     if(sticknumber == stnum)
      21:         return true;
      22:     for(int i = pos+1;i<n;++i)
      23:     {
      24:         if(visit[i] == 0 && curlen+segment[i] == sticklen)
      25:         {
      26:             visit[i] = 1;
      27:             if(dfs(sticknumber+1,0,-1,sticklen))
      28:                 return true;
      29:             visit[i] = 0;
      30:             return false;             //大的都不行,用小的凑起来更加不行
      31:         }
      32:         else if(visit[i] == 0 && curlen+ segment[i] < sticklen)
      33:         {
      34:             visit[i] = 1;
      35:             if(dfs(sticknumber,curlen+segment[i],i,sticklen))
      36:                 return true;
      37:             visit[i] = 0;
      38:             if(curlen==0) return false;         // 当前这个是最大的 并且以它开始匹配没有找到答案 肯定不行
      39:             while(segment[i] == segment[i+1]) i++;
      40:         }
      41:     }
      42:     return false;
      43:     
      44: }
      45: int main()
      46: {
      47: #ifdef DEBUG
      48:     freopen("test.txt","r",stdin);
      49:     freopen("result.txt","w",stdout);
      50: #endif
      51:     while(scanf("%d",&n) && n)
      52:     {
      53:         int sum = 0;
      54:         maxv = 0;
      55:         for(int i=0;i<n;++i)
      56:         {
      57:             scanf("%d",segment+i);
      58:             if(segment[i] > maxv)
      59:                 maxv = segment[i];
      60:             sum+=segment[i];
      61:         }
      62:         qsort(segment, n, sizeof(int), Compare);
      63:         for(int i=maxv;i<=sum;++i)
      64:         {
      65:             if(sum%i ==0)
      66:             {
      67:                 memset(visit,0,sizeof(visit));
      68:                 stnum = sum/i;
      69:                 if(dfs(0,0,-1,i))
      70:                 {
      71:                     printf("%d\n",i);
      72:                     break;
      73:                 }
      74:             }
      75:         }
      76:     }
      77: #ifdef DEBUG
      78:     freopen( "CON", "w", stdout );
      79:     system("result.txt");
      80: #endif
      81: }
  • 相关阅读:
    Jenkins遇到问题一:jenkins配置权限不对导致无法登陆或者空白页面解决办法
    翻页功能的测试用例
    Jenkins学习二:Jenkins安装与配置
    Jenkins学习一:Jenkins是什么?
    Java MyEclipse下Ant build.xml简单实例详解
    Linux环境中Openfire安装指南
    Linux下查看文件和文件夹大小
    Tsung测试openfire服务器
    Windows环境中Openfire与Spark安装与配置指南
    解决-bash: lsb_release: command not found
  • 原文地址:https://www.cnblogs.com/bovine/p/2372522.html
Copyright © 2011-2022 走看看