对于最优解我们发现所有的最优解都可以是前多少多少个,那么我们就二分这个前多少多少个,然后用dfs去判解,我们发现在dfs的过程中如果不剪枝几乎必T,所以我们就需要一些有效的剪枝 I. 我们在枚举过程中每个数选什么是有前后顺序的,然而对于一些相同的数他们并没有顺序我们可以记录上个数的选择点,如果两数相同,那么就从上个数的选择点开始那么时间复杂度就从次方级别降到了组合数级别,是飞跃式的 II. 然后我们发现先对于枚举顺序与选择顺序的选择是玄学的,我们可以视为他们都没影响那么我们就可利用这个了,如果我们倒着走枚举顺序那么我们可以把剩下的长度小于最小木板的木材删去,然后如果全部的减去删掉的小于需要的就退出。

对于搜索,我们有许多明显的减枝,那些都必须要减掉,然而有一些看似不起眼的小减枝在有的数据里往往会发挥很大的作用因此我们不能放弃任何一个减枝的机会。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define Max(a,b) a>b?a:b;
const int M=;
const int N=;
const int K=;
int g[M],f[N],n,m,ans,s[N],S;
bool die[M];
inline void read(){
scanf("%d",&m);
for(int i=;i<=m;i++)
scanf("%d",&g[i]);
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&f[i]);
std::sort(g+,g+(m+));
std::sort(f+,f+(n+));
while(f[n]>g[m]&&n>)n--;
int z=,tot;
while(f[]>g[z]&&z<=m)z++;
tot=m-z+;
for(int i=,j=z;i<=tot;i++,j++)
g[i]=g[j],S+=g[i];
for(int i=;i<=n;i++)s[i]=s[i-]+f[i];
m=tot;
}
bool dfs(int pos,int mid,int last,int key,int waste){
if(pos==)return true;
if(waste+s[mid]>S)return false;
for(int i=(f[pos]==key?last:);i<=m;i++)
if(g[i]>=f[pos]){
g[i]-=f[pos];
if(g[i]<f[])waste+=g[i];
if(dfs(pos-,mid,i,f[pos],waste)){
g[i]+=f[pos];
return true;
}
if(g[i]<f[])waste-=g[i];
g[i]+=f[pos];
}
return false;
}
int main(){
read();
int l=,r=n,mid;
while(l<=r){
mid=(l+r)>>;
if(dfs(mid,mid,,,))
ans=mid,l=mid+;
else
r=mid-;
}
printf("%d",ans);
return ;
}

【BZOJ 1082】[SCOI2005]栅栏 二分+dfs的更多相关文章

  1. [BZOJ 1082] [SCOI2005] 栅栏 【二分 + DFS验证(有效剪枝)】

    题目链接:BZOJ - 1082 题目分析 二分 + DFS验证. 二分到一个 mid ,验证能否选 mid 个根木棍,显然要选最小的 mid 根. 使用 DFS 验证,因为贪心地想一下,要尽量先用提 ...

  2. bzoj 1082: [SCOI2005]栅栏 题解

    1082: [SCOI2005]栅栏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2340  Solved: 991[Submit][Status] ...

  3. bzoj 1082: [SCOI2005]栅栏【二分+dfs】

    二分答案,dfs判断是否可行,当b[k]==b[k-1]时可以剪枝也就是后移枚举位置 #include<iostream> #include<cstdio> #include& ...

  4. bzoj 1082: [SCOI2005]栅栏

    Description 农夫约翰打算建立一个栅栏将他的牧场给围起来,因此他需要一些特定规格的木材.于是农夫约翰到木材店购 买木材.可是木材店老板说他这里只剩下少部分大规格的木板了.不过约翰可以购买这些 ...

  5. [SCOI2005]栅栏 二分+dfs

    这个题真的是太nb了,各种骚 二分答案,肯定要减最小的mid个,从大往小搜每一个木板,从大往小枚举所用的木材 当当前木材比最短的木板还短,就扔到垃圾堆里,并记录waste,当 waste+sum> ...

  6. bzoj1082: [SCOI2005]栅栏(二分答案搜索判断)

    1082: [SCOI2005]栅栏 题目:传送门 题解: 是不是一开始在想DP?本蒟蒻也是qwq,结果很nice的错了ORZ 正解:二分+搜索 我们可以先把两种木材都进行排序,那么如果需要的最大木材 ...

  7. [BZOJ1082][SCOI2005]栅栏 二分+搜索减枝

    1082: [SCOI2005]栅栏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2430  Solved: 1034[Submit][Status ...

  8. Bzoj 1085: [SCOI2005]骑士精神 (dfs)

    Bzoj 1085: [SCOI2005]骑士精神 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 dfs + 剪枝. 剪枝方法: ...

  9. 【BZOJ】1082: [SCOI2005]栅栏(二分+dfs)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1082 题意:n个给出木板,m个给出木板.可以将那m个木板锯成泥想要的长度.问最大能锯成多少个给出的n ...

随机推荐

  1. C语言关于指针的注意事项

    一.指针的四个关键概念1.指针的类型2.指针指向的类型3.指针的值,也就是指针指向的地址4.指针自己所占用的内存空间注意:指针变量所存的内容就是内存的地址编号! 例如:int **pp = NULL; ...

  2. stm32+lwip(二):UDP测试

    我是卓波,很高兴你来看我的博客. 系列文章: stm32+lwip(一):使用STM32CubeMX生成项目 stm32+lwip(二):UDP测试 stm32+lwip(三):TCP测试 stm32 ...

  3. Android面试收集录 数据库

    1.SQLite数据库如何查询表table1的第20条到30条记录? select * from table1 limit 19,11   ==>从19开始,11个数据 2.如何才能将table ...

  4. Python正则表达式中的re.S,re.M,re.I的作用

    正则表达式可以包含一些可选标志修饰符来控制匹配的模式.修饰符被指定为一个可选的标志.多个标志可以通过按位 OR(|) 它们来指定.如 re.I | re.M 被设置成 I 和 M 标志: 修饰符 描述 ...

  5. LeetCode:21. Merge Two Sorted Lists(Easy)

    1. 原题链接 https://leetcode.com/problems/merge-two-sorted-lists/description/ 2. 题目要求 给出两个已经从小到大排序的链表ls1 ...

  6. 【数据库】 SQLite 介绍

    [数据库] SQLite 介绍 一. 特点 : 小而精悍 1. 轻量级 : 占用资源低 2. 嵌入式 : 无需安装,直接引用就可用 3. 支持 SQL 语法, 大部分兼容 Sql Server 语法, ...

  7. es6中类的注意事项

    class Circle { constructor(radius) { this.radius = radius; Circle.circlesMade++; }; static draw(circ ...

  8. React切换显示和隐藏

    1 {radioChange >= 0 && 2 <div> 3 {radioChange === 0 ? ( 4 <div className={style. ...

  9. java设计模式之命令模式以及在java中作用

    命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或交易(Transaction)模式. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请 ...

  10. CentOS7安装配置SonarQube

    一.SonarQubeServer 1.前提 安装好mysql5.7和jdk1.8. (1)安装Mysql create user 'sonar'@'localhost' identified by ...