首先,长度短的木板一定比长度长的木板容易得到,因此若要得到最多的木板,它们必定是所有木板中最短的——可以对木板排序后二分答案(用k表示)。

  判断是否合法就用搜索,但数据有点大,要用到两个剪枝。一个是若有一根木材被切开后剩下的长度比最短的木板还短则将其累加入waste,当waste+前k块木板的长度和>木材的总长度时即可return(这十分显然);二是把木材也排序,木板从大到小去搜索而木板从小到大去枚举,若当前的木板长度与上一块木板相同,则从切出上一块木板的木材开始枚举(之前的木材肯定不够用),否则从第一根开始枚举。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi acos(-1.0)
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... int m, n, a[], b[], sumb[], f[], sum, waste, mid; bool dfs(int x, int last)
{
if (!x) return true;
if (waste+sumb[mid]>sum) return false;
int res=false;
int t=(b[x]==b[x+]?last:);
FOR(i,last,m) if (a[i]>=b[x]) {
a[i]-=b[x];
if (a[i]<b[]) waste+=a[i];
res|=dfs(x-,b[x]==b[x-]?i:);
if (res) return res;
if (a[i]<b[]) waste-=a[i];
a[i]+=b[x];
}
return res;
}
int main ()
{
int ma=;
scanf("%d",&m);
FOR(i,,m) scanf("%d",f+i), sum+=f[i], ma=max(ma,f[i]);
sort(f+,f+m+);
scanf("%d",&n);
FOR(i,,n) scanf("%d",b+i);
sort(b+,b+n+);
int l=, r=n+;
FOR(i,,n) {
sumb[i]=sumb[i-]+b[i];
if (sum<sumb[i]) r=min(r,i);
if (ma<b[i]) r=min(r,i);
}
if (sum>=sumb[n]&&ma>=b[n]) r=n+;
while (l<r) {
mid=(l+r)>>;
if (l==mid) break;
waste=;
FOR(i,,m) a[i]=f[i];
if (dfs(mid,)) l=mid;
else r=mid;
}
printf("%d\n",l);
return ;
}

BZOJ 1082 栅栏(二分+DFS剪枝)的更多相关文章

  1. 【BZOJ 1082】[SCOI2005]栅栏 二分+dfs

    对于最优解我们发现所有的最优解都可以是前多少多少个,那么我们就二分这个前多少多少个,然后用dfs去判解,我们发现在dfs的过程中如果不剪枝几乎必T,所以我们就需要一些有效的剪枝 I. 我们在枚举过程中 ...

  2. [SCOI2005]栅栏 二分+dfs

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

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

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

  4. Black And White(DFS+剪枝)

    Black And White Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others ...

  5. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  6. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  7. Codeforces Round #381 (Div. 2)D. Alyona and a tree(树+二分+dfs)

    D. Alyona and a tree Problem Description: Alyona has a tree with n vertices. The root of the tree is ...

  8. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  9. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

随机推荐

  1. LeetCode: 54. Spiral Matrix(Medium)

    1. 原题链接 https://leetcode.com/problems/spiral-matrix/description/ 2. 题目要求 给定一个二维整型数组,返回其螺旋顺序列表,例如: 最后 ...

  2. Jsp刷新分页模板,很全

      1.用来实现上一页下一页,我直接写到查询页面上 <%--page的分页--%> <style type="text/css"> a { color: # ...

  3. SpringBoot-07:SpringBoot整合PageHelper做多条件分页查询

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客讲述如何在SpringBoot中整合PageHelper,如何实现带多个条件,以及PageInfo中的 ...

  4. Python Map 并行

    Map是一个酷酷的小东西,也是在Python代码轻松引入并行的关键.对此不熟悉的人会认为map是从函数式语言(如Lisp)借鉴来的东西.map是一个函数 - 将另一个函数映射到一个序列上.例如: ur ...

  5. linux常用的命令之一chmod

    用权限 : 所有使用者 使用方式 : chmod [-cfvR] [--help] [--version] mode file... u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(g ...

  6. WEB网站测试心得整理

    一.输入框: 1.正常的字母/文字/数字(正常流程的测试): 2.重复提交(输入内容后,重复点击提交按钮): 3.纯异常字符/正常输入夹杂异常字符(!@#¥%……&**等等): 4.长度限制( ...

  7. Web自动化selenium技术快速实现爬虫

    selenium是大家众所周知的web自动化测试框架,主要用来完成web网站项目的自动化测试,但其实如果要实现一个web爬虫,去某些网站爬取数据,其实用selenium来实现也很方便. 比如,我们现在 ...

  8. 【WXS数据类型】Object

    Object 是一种无序的键值对. 属性: 名称 值类型 说明 [Object].constructor [String] 返回值为“Object”,表示类型的结构字符串 方法: 原型:[Object ...

  9. hexo部署失败如何解决

  10. JAVA基础学习之路(四)定义简单java类

    简单java类开发一般原则: 类名称必须有意义,再怎么说,要让人家看的明白吧 类之中所有属性必须使用private封装,并提供setter,getter方法 类之中可以有多个构造方法,但是必须保留有一 ...