usaco4.12Fence Rails(迭代加深)
为了这题还去学了下迭代加深 回来还是不会写
只好参考各大神的代码及题解了
二分枚举最大可以切的块数 然后就是各种分析及优化
USACO题解里写了7个优化。。
问题分析
抽象一下就可以发现,算法的本质是多重背包问题。 补充:这题与破锣乐队都是多个背包,不可重复放物品。区别在于破锣乐队要有顺序,此题不需要,这样此题就必须要搜索才行。 单个背包的问题我们可以用DP解决,但是对于这种问题我们只能用搜索了。 但是可以看一看这道题的数据规模:1<=n<=50,1<=r<=1023。如此大的规模我们只能考虑进一步的优化。
我采用的是dfsid搜索每一个rail来源的board。以下技巧都是针对这种搜索顺序来制定的。 (注:rail是所需要切成的东西,board是供应商提供的原料)
如果使用dancing links的话,可以让程序的常数快2倍。
优化技巧
- 很容易就能注意到,由于每块rail的价值是相等的——也就是说切小的要比切大的来的划算。那么我们在搜索能否切出i个rail的方案是自然要选最小的i个rail来切。
- 经过一些实验可以发现,先切大的rail比先切小的rail更容易提前出解。同样,[先切小的board比先切大的board更容易提前出解?]{注:好像先切大的board要比先切小的更快}。{*我的程序先切小再切大第5个点就TLE了,而先切大再切小就快很多,见C++程序.{跟我一样,握个手,一定要先大后小!!!}}
- 由于r最大可能是1023,但是rail长度的范围却只有0~128,这点提醒了我们有很多rail的长度会是相同的。所以我们要避免冗余,优化搜索顺序。若有rail[i+1]=rail[i],则rail[i+1]对应的board一定大于等于rail[i]对应的board。可以通过这种方法剪掉很多冗余的枝条。
- 相应的,如果board[i]=board[i+1],那么从board[i]切下的最大的rail一定大于等于从board[i+1]切下的最大的rail。
- 对于切剩下的board(无法再切下rail),统计一下总和。如果这个值大于board长度的总和减去rail长度的总和,一定无解,可以剪枝。这个剪枝最关键。
- 二分答案
- 其实在读入的过程中,如果rail[i] > max{board} 那么这个rail应该舍去 By Clarkok
/*
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(迭代加深)的更多相关文章
- POJ1129Channel Allocation[迭代加深搜索 四色定理]
Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14601 Accepted: 74 ...
- BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1800 Solved: 984[Submit][Statu ...
- 迭代加深搜索 POJ 1129 Channel Allocation
POJ 1129 Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14191 Acc ...
- 迭代加深搜索 codevs 2541 幂运算
codevs 2541 幂运算 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 从m开始,我们只需要6次运算就可以计算出 ...
- HDU 1560 DNA sequence (IDA* 迭代加深 搜索)
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1560 BFS题解:http://www.cnblogs.com/crazyapple/p/321810 ...
- poj2286The Rotation Game(迭代加深dfs)
链接 把迭代加深理解错了 自己写了半天也没写对 所谓迭代加深,就是在深度无上限的情况下,先预估一个深度(尽量小)进行搜索,如果没有找到解,再逐步放大深度搜索.这种方法虽然会导致重复的遍历 某些结点,但 ...
- IOI1994 北京2008的挂钟 迭代加深
总的来讲,这是一道很⑨的题,因为: (1)题目中有⑨个挂钟 (2)有⑨种操作方案 (3)这题因为解空间太小所以可以直接⑨重循环!! 这题可以用迭代加深搜索高效求解,剪枝的策略也很显然: >所求的 ...
- 迭代加深搜索算法总结 + Editing a Book UVa11212题解
迭代加深搜索算法: 对于可以用回溯法解决,但是解答树结点数大的恐怖的问题的一种解决办法,有的问题甚至用bfs连一层节点都遍历不完就超时了.具体方法就是依次枚举搜索层数,从1到一个上限. 结构: int ...
- codevs 2541 幂运算(迭代加深搜索)
/* 一开始想到了简单的深搜 维护当前可用的mi数组 然后回溯用哪个 不断更新新产生的mi 这样的问题是 由于mi不断产生 搜索规模扩大 不好 不好 下面是奇丑的WA掉的代码 做个反面教材 */ #i ...
随机推荐
- IOS 应用程序启动加载过程(从点击图标到界面显示)
今天帮同事解决问题的时候发现,程序BUG是由加载过程引起的.所以当局部代码没有问题,但是程序一运行却总不是我们想要结果的时候,我们应该想想是不是因为我们忽略了试图加载过程的原因.下面我们用一个例子来简 ...
- IOS- 最简单的反向传值- block
block 常用于反向传值 声明 返回值类型 (^block)(参数列表) 调用 闭包的名字=^(参数列表){}: 闭包的名字(): 如: void(^aaaaa)(int num,NSString ...
- C#中常用修饰符
1.存取修饰符 public:(公有的)存取不受限制 protected:(受保护的)只有包含该成员的类以及派生类可以存取 private:(私有的)只有包含该成员的类可以使用 2.类修饰符 abs ...
- php封装文件上传
这是一个经常在项目中遇到的问题,所以封装一个,分享给大家. 一,前期配置php.ini 如果上传文件超过了php配置那么$_POST或者$_FILES等都是空数组,这点是一个坑,因为那时候就不 ...
- Struts1运行原理以及整合步骤
Struts1 struts1运行步骤 1.项目初始化:项目启动时加载web.xml,struts1的总控制器ActionServlet是一个Servlet,它在web.xml中是配置成自动启动的S ...
- Java实战之02Hibernate-03Session中的常用方法
九.Session中的常用方法 1.save方法 都是临时态————>持久态 2.persist方法 作用: 持久化临时态对象. 与save方法的区别: 开始了事务:persist和save没有 ...
- HDU 4422 The Little Girl who Picks Mushrooms(简单题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4422 题目大意:小姑娘背着5个包去山上采蘑菇,每座山上只能用一个背包采集.三个小精灵会要她3个背包,其 ...
- 多站点FTP同步
需求描述: 由于工作的原因,发布程序时,经常需要将一站点的脚本.程序同步到其它的终端站点中,以保证所有站点的程序是同步的,用过FlashFtp,CuteFtp,LeapFtp等客户端工具,均于自己的需 ...
- Oracle OEM重建
参考博客:http://blog.csdn.net/tianlesoftware/article/details/4702978 测试环境: C:\Users\Administrator>sql ...
- HBASE的安装
HBASE的安装: 安装的软件版本:hbase-0.98.4-hadoop2.tar.gz 下载链接:http://www.apache.org/dist/hbase/hbase-0.98.4/ 1. ...