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

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

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

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. 常用终端及git命令

    终端常用命令 1,打开终端,git version 查看版本 2,pwd 打印工作目录 3,ls(list简写)查看当前目录的所有文件 4,clear 清掉屏幕 5,cd (change direct ...

  2. [转载]浅析STL allocator

    本文转载自水目沾博客:http://www.cnblogs.com/zhuwbox/p/3699977.html   向大师致敬 一般而言,我们习惯的 C++ 内存配置操作和释放操作是这样的: 1 c ...

  3. Android中的EditText默认时不弹出软键盘的方法

    方法一: 在 AndroidMainfest.xml中选择哪个activity,设置windowSoftInputMode属性为 adjustUnspecified|stateHidden <a ...

  4. vsftpd.conf配置详解

    根据 /etc/vsftpd/vsftpd.conf默认配置给出设定功能   # Example config file /etc/vsftpd/vsftpd.conf # The default c ...

  5. 目前IT行业的几个大方向

    我简单总结了一下目前it行业的8大方向:   1.嵌入式开发 传统的arm linux开发.新兴的智能硬件.物联网等技术的发展,都让整个方向成为热门领域.   2.游戏开发 cocos2d-x.uni ...

  6. Win7 钩子 超时 失效

    这段时间在程序中,使用了全局钩子,但是在测试时发现,会偶尔失效. 在网上搜索到了这两篇文章: VC底层钩子程序在Win7/Vista下无效 Hooking problem in Windows 7 这 ...

  7. DataNavigator之分页

    前言 做客户端也有两个月了,先前做列表都没有分页,可能考虑数据也不是很多,昨天做了一个页面,考虑到了数据的问题,所以改为分页查询.因为也是第一次用dev,用哪个控件分页呢,还是要去搜一下,得出的事Da ...

  8. 转.....IOC 和DI

    引述:IoC(控制反转:Inverse of Control)是Spring容器的内核,AOP.声明式事务等功能在此基础上开花结果.但是IoC这个重要的概念却比较晦涩隐讳,不容易让人望文生义,这不能不 ...

  9. Spring 官方下载地址(非Maven)

    现在spring的官网停止了使用zip包下载,只能使用maven,非常的不方便,分享如下网址可以使用zip包下载,是不是方便多了!~ 下载列表如下: spring-framework-3.2.8.RE ...

  10. HttpWebRequest中的KeepAlive

    一直不是非常理解.NET中HttpWebRequest的KeepAlive属性有何用处,看了这篇文章就清楚了! http://www.cnblogs.com/lwzz/archive/2011/08/ ...