为了这题还去学了下迭代加深 回来还是不会写

只好参考各大神的代码及题解了

二分枚举最大可以切的块数 然后就是各种分析及优化

USACO题解里写了7个优化。。

问题分析

抽象一下就可以发现,算法的本质是多重背包问题。 补充:这题与破锣乐队都是多个背包,不可重复放物品。区别在于破锣乐队要有顺序,此题不需要,这样此题就必须要搜索才行。 单个背包的问题我们可以用DP解决,但是对于这种问题我们只能用搜索了。 但是可以看一看这道题的数据规模:1<=n<=50,1<=r<=1023。如此大的规模我们只能考虑进一步的优化。

我采用的是dfsid搜索每一个rail来源的board。以下技巧都是针对这种搜索顺序来制定的。 (注:rail是所需要切成的东西,board是供应商提供的原料)

如果使用dancing links的话,可以让程序的常数快2倍。

优化技巧

  1. 很容易就能注意到,由于每块rail的价值是相等的——也就是说切小的要比切大的来的划算。那么我们在搜索能否切出i个rail的方案是自然要选最小的i个rail来切。
  2. 经过一些实验可以发现,先切大的rail比先切小的rail更容易提前出解。同样,[先切小的board比先切大的board更容易提前出解?]{注:好像先切大的board要比先切小的更快}。{*我的程序先切小再切大第5个点就TLE了,而先切大再切小就快很多,见C++程序.{跟我一样,握个手,一定要先大后小!!!}}
  3. 由于r最大可能是1023,但是rail长度的范围却只有0~128,这点提醒了我们有很多rail的长度会是相同的。所以我们要避免冗余,优化搜索顺序。若有rail[i+1]=rail[i],则rail[i+1]对应的board一定大于等于rail[i]对应的board。可以通过这种方法剪掉很多冗余的枝条。
  4. 相应的,如果board[i]=board[i+1],那么从board[i]切下的最大的rail一定大于等于从board[i+1]切下的最大的rail。
  5. 对于切剩下的board(无法再切下rail),统计一下总和。如果这个值大于board长度的总和减去rail长度的总和,一定无解,可以剪枝。这个剪枝最关键。
  6. 二分答案
  7. 其实在读入的过程中,如果rail[i] > max{board} 那么这个rail应该舍去 By Clarkok
  8.  /*
    ID: shangca2
    LANG: C++
    TASK: fence8
    */
    #include <iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<stdlib.h>
    using namespace std;
    int bo[],te[],ra[],v;
    int n,m,res,s,sum[],flag;
    void dfs(int tt,int st)
    {
    int i;
    if(flag) return ;
    if(tt==)//全部可以切完
    {
    flag = ;
    return ;
    }
    int ss=,o;
    for(i = ; i <= n ; i++)//当前木板剩余值已经大于最多的剩余值 肯定不用再搜
    { if(te[i]<ra[])
    ss+=te[i];
    }
    if(ss>v) return ;
    for(i = st ; i <= n ; i++)
    {
    if(te[i]>=ra[tt])
    { if(tt->=&&ra[tt]==ra[tt-])//一个小优化 如果ra[tt]已经在i~N里搜了 那么前面跟它相等的 就不会在i之前搜了
    o = i;
    else
    o = ;
    te[i]-=ra[tt];
    dfs(tt-,o);
    te[i]+=ra[tt];
    }
    }
    return ;
    }
    int main()
    {
    //freopen("fence8.in","r",stdin);
    //freopen("fence8.out","w",stdout);
    int i;
    cin>>n;
    for(i = ; i <= n ; i++)
    {
    scanf("%d",&bo[i]);
    s+=bo[i];
    }
    sort(bo+,bo+n+);
    for(i = ; i <= n ; i++)
    te[i] = bo[i];
    scanf("%d",&m);
    for(i = ; i <= m ; i++)
    {
    scanf("%d",&ra[i]); }
    sort(ra+,ra+m+);
    for(i = ; i <= m ; i++)
    sum[i] = sum[i-]+ra[i];
    int low=,high = m;
    while(low<high)//二分找一下 满足最多可以切多少块
    {
    int mm = (low+high+)>>;
    v = s-sum[mm];
    flag = ;
    dfs(mm,);
    if(flag)
    low = mm;
    else
    high = mm-;
    }
    printf("%d\n",low);
    return ;
    }

usaco4.12Fence Rails(迭代加深)的更多相关文章

  1. POJ1129Channel Allocation[迭代加深搜索 四色定理]

    Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14601   Accepted: 74 ...

  2. BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1800  Solved: 984[Submit][Statu ...

  3. 迭代加深搜索 POJ 1129 Channel Allocation

    POJ 1129 Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14191   Acc ...

  4. 迭代加深搜索 codevs 2541 幂运算

    codevs 2541 幂运算  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 从m开始,我们只需要6次运算就可以计算出 ...

  5. HDU 1560 DNA sequence (IDA* 迭代加深 搜索)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1560 BFS题解:http://www.cnblogs.com/crazyapple/p/321810 ...

  6. poj2286The Rotation Game(迭代加深dfs)

    链接 把迭代加深理解错了 自己写了半天也没写对 所谓迭代加深,就是在深度无上限的情况下,先预估一个深度(尽量小)进行搜索,如果没有找到解,再逐步放大深度搜索.这种方法虽然会导致重复的遍历 某些结点,但 ...

  7. IOI1994 北京2008的挂钟 迭代加深

    总的来讲,这是一道很⑨的题,因为: (1)题目中有⑨个挂钟 (2)有⑨种操作方案 (3)这题因为解空间太小所以可以直接⑨重循环!! 这题可以用迭代加深搜索高效求解,剪枝的策略也很显然: >所求的 ...

  8. 迭代加深搜索算法总结 + Editing a Book UVa11212题解

    迭代加深搜索算法: 对于可以用回溯法解决,但是解答树结点数大的恐怖的问题的一种解决办法,有的问题甚至用bfs连一层节点都遍历不完就超时了.具体方法就是依次枚举搜索层数,从1到一个上限. 结构: int ...

  9. codevs 2541 幂运算(迭代加深搜索)

    /* 一开始想到了简单的深搜 维护当前可用的mi数组 然后回溯用哪个 不断更新新产生的mi 这样的问题是 由于mi不断产生 搜索规模扩大 不好 不好 下面是奇丑的WA掉的代码 做个反面教材 */ #i ...

随机推荐

  1. 比之前那个版本更简单的C语言实现的比较大小

    之前那个是输入一堆数据,找最大那个,这次是更简单的版本,求两个数的最大值. #include "stdafx.h" #include <stdio.h> int Get ...

  2. springmvc学习(三)

    第一点---------使用 @RequestMapping 映射请求• Ant 风格资源地址支持 3 种匹配符:?:匹配文件名中的一个字符 *:匹配文件名中的任意字符 **:** 匹配多层路径 @R ...

  3. Java 与 Python 的对比

    最近在学习Python, 现在写一个Python程序和Java程序进行对一下比,以此展示各自不同的特点.这个程序的功能是计算([n, m) )之间的闰年.     Python程序如下: def fu ...

  4. 【nodemailer】之 work with mustache

    之前对nodemailer做了简要的研究,基本上是搞定了发邮件的问题.但很多情况下邮件的内容不是固定的,然后又需要有一个合适的样式,这就需要使用模板了.nodemailer有nodemailer-ma ...

  5. python 自动化之路 day 04

    内容目录: 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 4.嵌套函数 5.递归 6.匿名函数 7.函数式编程介绍 8.高阶函数 9.内置函数 1.函数基本语法及特性 背景提要 现在老 ...

  6. Oracle 自连接 / 外连接 / 子查询

    --连接查询的三种格式 select ename, deptno,dname from emp natural join dept; select ename, deptno,dname from e ...

  7. Html5页面返回机制解决方案

    需要处理的返回场景: 1.正常的a->b->c 2.页面上的按钮触发需要登陆 3.页面跳转需要登陆 4.页面上的可修改的部分(如选择地址,地址页面本身也是可以增删改查的) 整体的原则是原路 ...

  8. logback使用笔记

    三大主要元素 looger:记录日志 appender:输出目的地 layout:输出格式 必要步骤: 一.引入包: import org.slf4j.Logger; import org.slf4j ...

  9. Python 3.5 for windows 10 通过pip安装mysqlclient模块 error:C1083

    $pip install mysqlclient 运行结果如下: 可能是由于不兼容导致的(中间试过各种方法,比如本地安装mysql等等),最后找来mysqlclient-1.3.7-cp35-cp35 ...

  10. MVC-EditorFor与TextBoxFor的区别

    EditorFor会根据后面提供的数据类型自动判断生成的控件类型(比如TextBox,CheckBox等): TextBoxFor生成的只是一个TextBox.