http://www.lydsy.com/JudgeOnline/problem.php?id=1082

题意:n个给出木板,m个给出木板。可以将那m个木板锯成泥想要的长度。问最大能锯成多少个给出的n个木板。(n<=1000, m<=50)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const int N=2005;
int v[N], n, m, w[N], sum[N], c[N], tot, rest; bool dfs(int dep, int last) {
if(!dep) return true;
if(rest+sum[dep]>tot) return false;
for1(i, last, n) {
if(c[i]>=w[dep]) {
c[i]-=w[dep];
if(c[i]<w[1]) rest+=c[i];
if(w[dep]==w[dep-1]) { if(dfs(dep-1, i)) return true; }
else if(dfs(dep-1, 1)) return true;
if(c[i]<w[1]) rest-=c[i];
c[i]+=w[dep];
}
}
return false;
}
bool check(int d) {
memcpy(c, v, sizeof(int)*(n+1));
rest=0;
return dfs(d, 1);
}
int main() {
read(n);
for1(i, 1, n) read(v[i]), tot+=v[i];
sort(v+1, v+1+n);
read(m);
for1(i, 1, m) read(w[i]);
sort(w+1, w+1+m);
for1(i, 1, m) sum[i]=sum[i-1]+w[i];
while(sum[m]>tot) --m;
int l=0, r=m, mid;
while(l<=r) {
mid=(l+r)>>1;
if(check(mid)) l=mid+1;
else r=mid-1;
}
print(l-1);
return 0;
}

最近被这种神题虐cry。。。这还竟然是usaco的题QAQ我竟然如此弱。。。。(我是不是写过这题?反正好像有点印象的样子。。好像又不是。。)

一开始写了个背包。。。贪心的找。。。。。。。。。。。。。。。。然后造了几个数据,,wa了。。

QAQ

膜拜题解。orz

首先我们得到的k个木板一定是在n个中最小的k个。。。(这个太显然了QAQ

我们考虑将m个提供的木材,依次从最小的放(显然先用完最短的。。。)

所以将k个木板和m个提供的木材排序后再做。。。。。

二分k,判定是否能得到。。。

那么就是暴力枚举前k个的放法,可是。。2^1000。。。。tle成翔。。。。。。。。

倒序枚举

那么考虑剪枝orz

首先如果当一个提供的木材小于了最小的所需木板,那么我们用个rest累加,当rest+sum[k]>tot时,剪掉(sum[k]表示前k个所需木板长度,tot表示提供木板的总量(其实这个剪枝还不够呢。。。因为tot是静态的,并没有变动。。。反正不改也能a))

然后继续剪枝,当k木板等于k-1木板的长度,那么我们不需要从1枚举木材了,因为此时k木板从哪个枚举说明前面的都不够了。。所以直接从k木板当前的木材枚举k-1。。

然后能水过了。。

【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去判解,我们发现在dfs的过程中如果不剪枝几乎必T,所以我们就需要一些有效的剪枝 I. 我们在枚举过程中 ...

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

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

  5. bzoj 1082: [SCOI2005]栅栏

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

  6. [SCOI2005]栅栏 二分+dfs

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

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

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

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

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

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

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

随机推荐

  1. Linux 高可用开源方案 Keepalived VS Heartbeat对比

    1)Keepalived使用更简单:从安装.配置.使用.维护等角度上对比,Keepalived都比Heartbeat要简单得多,尤其是Heartbeat2.1.4后拆分成3个子项目,安装.配置.使用都 ...

  2. 12 day 1

    #include <cstdio> int i,j,m,n,t; long long f[6000][6000]; inline int min(int a,int b){ return ...

  3. C语言指针总结

    C语言中的精华是什么,答曰指针,这也是C语言中唯一的难点. C是对底层操作非常方便的语言,而底层操作中用到最多的就是指针,以后从事嵌入式开发的朋友们,指针将陪伴我们终身. 本文将从八个常见的方面来透视 ...

  4. recv和send函数

    转自  http://www.cnblogs.com/blankqdb/archive/2012/08/30/2663859.html 1. send解析 sockfd:指定发送端套接字描述符. bu ...

  5. 字符编码浅识:关于Unicode与UTF-8

    参考自阮一峰博客:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html Unicode只是一个符号集,它只规定了符号的 ...

  6. css 之盒子模型

    display: none  inline   block float :none   right   left clear  left   right  both    清除浮动  是清楚它之前的左 ...

  7. AES 推荐文章

    链接如下,写得很好!http://blog.csdn.net/a00553344/article/details/4002507

  8. oracle 10g 学习之创建和管理表(7)

    目标 通过本章学习,您将可以: l  描述主要的数据库对象. l  创建表. l  描述各种数据类型. l  修改表的定义. l  删除,重命名和清空表. 常见的数据库对象 表.视图.序列.索引.同义 ...

  9. express再学习

    对比spring,django,再学习express就有很多共通的地方啦... 看的书是一本小书,<express in action>,排版比较好. 昨天开始看,看了快四分之一啦... ...

  10. 【HTML5】表单元素

    * datalist datalist 元素规定输入域的选项列表. 列表是通过 datalist 内的 option 元素创建的. 如需把 datalist 绑定到输入域,请用输入域的 list 属性 ...