• uestc sticks


    转自http://m.blog.csdn.net/blog/wuxinliulei/9052707

    Sticks
      这一题仍然要采用深度优先搜索+剪枝 
      这一题的剪枝很重要。
      首先题意是要求木棒的最短长度,首先明确一点木棒的长度一定在最长木棒长度---所有木棒长度总和之间
      所以在读入木棒长度之后要找出最长的和长度总和两个值。
      还有一个理论上分析得出的结果   就是长木棒的灵活性较小在拼接的时候要首先拼接长木棒再考虑短木棒
      比如要拼接一个长度为8的木棒  拼接 5+3 和拼接 5+2+1 其实是等价的 但是显然前者对3的利用较好
      所以在读入数据之后对木棒的长度进行排序。从大到小。
      然后从最大木棒长度  就是数组的第一个元素开始进行枚举,
      此时又出现一个剪枝 就是长度必须是总和的约数  这个也是自然的。
      下面进行深搜
      深搜的结束条件此时也是一个剪枝 当已经组合的(木棍长度+1)* 长度之后如果等于总和则 return true 跳出循环 得出结果
      下面的判断分为三种情况  新加上的木棒长度刚好构成一个完整的木棒  还有不能构成一个完整的木棒 
      还有细分出来的起始长度为0无法构成一个完成木棒的情况 ,这是一个剪枝 如果在这种情况下都无法完成的话说明不可能在利用这个
     木棒,于是return false  这是为一个一个在for循环里的return false 不然的话都要将for循环进行到底(除非return true)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 using namespace std;
     7 #define MAX 64
     8 
     9 
    10 int s[MAX], vis[MAX], n, len, sum;
    11 
    12 
    13 bool cmp(int a, int b) 
    14 {
    15     return a > b;
    16 }
    17 
    18 void input()
    19 {
    20     int i, j, temp;
    21     sum = 0;
    22     for (i = 0; i<n; i++)
    23     {
    24         scanf("%d ", &s[i]);
    25         sum += s[i];
    26     }
    27     sort(s,s+n,cmp);
    28 }
    29 
    30 
    31 bool dfs(int now_len, int i, int count)
    32 {
    33     if ((count + 1)*len == sum)
    34     {
    35         return true;
    36     }
    37     for (int k = i; k<n; k++)
    38     {
    39         if (vis[k]) continue;
    40         if (k&&!vis[k - 1] && s[k] == s[k - 1]) continue;
    41         if (s[k] + now_len>len) continue;
    42         if (now_len + s[k] == len)
    43         {
    44             vis[k] = 1;
    45             bool result = dfs(0, 0, count + 1);
    46             vis[k] = 0;
    47             return result;
    48         }
    49         else if (now_len == 0)
    50         {
    51             vis[k] = 1;
    52             bool result = dfs(s[k], k + 1, count);
    53             vis[k] = 0;
    54             return result;
    55 
    56 
    57         }
    58         else if (now_len + s[k]<len)
    59         {
    60             vis[k] = 1;
    61             bool result = dfs(s[k] + now_len, k + 1, count);
    62             vis[k] = 0;
    63             if (result)
    64                 return true;
    65         }
    66     }
    67     return false;
    68 }
    69 int main()
    70 {
    71     //freopen("1.txt","r",stdin);
    72     while (scanf("%d", &n) == 1 && n != 0)
    73     {
    74         input();
    75         for (len = s[0]; len <= sum; len++)
    76         {
    77             if (sum%len) continue;
    78             memset(vis, 0, sizeof(vis));
    79             if (dfs(0, 0, 0))
    80                 break;
    81         }
    82         printf("%d
    ", len);
    83     }
    84 }
  • 相关阅读:
    [GeeksForGeeks] Maximum Length Chain of Pairs
    [Coding Made Simple] Buy/Sell stock with at most K transactions to maximize profit
    [LeetCode 10] Regular Expression Matching
    056_统计/etc/passwd 中 root 出现的次数
    055_使用脚本循环创建三位数字的文本文件(111-999 的所有文件)
    054_自动修改计划任务配置文件
    053_修改 Linux 系统的最大打开文件数量
    052_获取本机 MAC 地址
    051_循环关闭局域网中所有主机
    050_显示进度条(回旋镖版)
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4259507.html
Copyright © 2020-2023  润新知