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

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

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

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. IOS开发之NSObject协议类方法说明

    oc中NSObject类是所有类的基类,所有类都要继承自它,那么它的方法就显得特别重要,因为所有类都会有这些基本的方法. 看看oc的源码中NSObject是这样定义的: @interface NSOb ...

  2. Mysql 的函数

    函数 MySQL函数分为系统函数与自定义函数 系统函数: pow(m,n)        求m的n次方 rand()            随机获取0至1之间的小数 floor();          ...

  3. WIX Custom Action (immediate, deffered, rollback)

    Following content is directly reprinted from From MSI to WiX, Part 19 - The Art of Custom Action, Pa ...

  4. java nio使用方法(转)

    最近由于工作关系要做一些Java方面的开发,其中最重要的一块就是Java NIO(New I/O),尽管很早以前了解过一些,但并没有认真去看过它的实现原理,也没有机会在工作中使用,这次也好重新研究一下 ...

  5. 防火墙,svn服务器端安装(yum),使用

    yum install subversion 查看安装位置 rpm -ql subversion 结果如下: svn在bin目录下生成了几个二进制文件 可以查看svn的使用方法 svn --help ...

  6. javascript调用外部wpf的方法

    今天因为项目需要在wpf嵌入web页面,然后在web页面调用wpf的方法,于是突击学习了一下,记下备忘.^_^ 1.wpf中新建一个类WpfForScriptingHelper namespace w ...

  7. ASP.NET MVC 搭建简单网站 --1.前端页面布局和基本样式实现

    学技术这件事儿本来就是学习现有的东西,然后变成自己的,本文当然也是借鉴的别人的东西,写出来作为一个对知识的巩固.  1.网站用的是MVC模式,新建一个MVC项目,建立一个APP1Controller, ...

  8. tp数据表字段缓存

    在维护一个tp写的项目,因为需要在产品表product中增加了一个字段status,但是不论如何就是无法给status赋值,查了资料才发现,原来是tp的数据表字段缓存在搞鬼. 在runtime> ...

  9. Python 强大而易用的文件操作(转载)

    在Python中可以很方便地做一些诸如浏览目录,创建文件夹,删除文件夹等等的操作. 对文件系统的访问大多通过os模块来实现,因为Python是多平台的,os模块只是前端,具体的实现还是由具体的系统来完 ...

  10. VS2013 调试卡顿

    今早好奇安装了花生壳远程控制软件.然后下午莫名的感觉到vs2013 调试特别的卡顿.会每隔1s中请求一次的那种卡顿于是卸载了花生壳控制软件,发现问题依旧.然后重启机器 ok了.果然不卡顿了. 我回忆了 ...