bzoj 1082: [SCOI2005]栅栏
Description
农夫约翰打算建立一个栅栏将他的牧场给围起来,因此他需要一些特定规格的木材。于是农夫约翰到木材店购
买木材。可是木材店老板说他这里只剩下少部分大规格的木板了。不过约翰可以购买这些木板,然后切割成他所需
要的规格。而且约翰有一把神奇的锯子,用它来锯木板,不会产生任何损失,也就是说长度为10的木板可以切成长
度为8和2的两个木板。你的任务:给你约翰所需要的木板的规格,还有木材店老板能够给出的木材的规格,求约翰
最多能够得到多少他所需要的木板。
解题报告
强力剪枝搜索题哈,看到数据范围,想到搜索就是个脑洞....
首先意识到需求的木板一定是最小的几个,所以排个序,枚举前缀....
考虑剪枝:
1.答案具有单调性,考虑二分或迭代,这里1000的范围选择二分
2.强力剪枝1:答案确定了,那么所需木材总量也确定了,我们考虑用掉这些总量的木材还剩下多少,如果已经用不上的木材已经超过了最多能剩下的木材,那么一定无解了
3.强力剪枝2:有一组数据很多相同的木材,因为同样的木材是等价的,可以视为一类,所以无先后顺序,所以可以记last去掉重复状态
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=1005;
int a[N],sum[N],n,m,tot,b[N],res,tr=0;
bool dfs(int x,int s){
int i,ret=0;
if(tr>res)return false;
if(x==0)return true;
for(i=s;i<=m;i++){
if(a[i]<b[x])continue;
a[i]-=b[x];
if(a[i]<b[1])tr+=a[i];
if(b[x]==b[x-1])ret=dfs(x-1,i);
else ret=dfs(x-1,1);
if(a[i]<b[1])tr-=a[i];
a[i]+=b[x];
if(ret)return true;
}
return false;
}
void work()
{
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]),tot+=a[i];
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+b[i];
int l=1,r=n,mid,ans=0;
while(l<=r){
mid=(l+r)>>1;
res=tot-sum[mid];tr=0;
if(dfs(mid,1))ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
}
int main(){work();return 0;}
bzoj 1082: [SCOI2005]栅栏的更多相关文章
- bzoj 1082: [SCOI2005]栅栏 题解
1082: [SCOI2005]栅栏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2340 Solved: 991[Submit][Status] ...
- [BZOJ 1082] [SCOI2005] 栅栏 【二分 + DFS验证(有效剪枝)】
题目链接:BZOJ - 1082 题目分析 二分 + DFS验证. 二分到一个 mid ,验证能否选 mid 个根木棍,显然要选最小的 mid 根. 使用 DFS 验证,因为贪心地想一下,要尽量先用提 ...
- bzoj 1082: [SCOI2005]栅栏【二分+dfs】
二分答案,dfs判断是否可行,当b[k]==b[k-1]时可以剪枝也就是后移枚举位置 #include<iostream> #include<cstdio> #include& ...
- 【BZOJ】1082: [SCOI2005]栅栏(二分+dfs)
http://www.lydsy.com/JudgeOnline/problem.php?id=1082 题意:n个给出木板,m个给出木板.可以将那m个木板锯成泥想要的长度.问最大能锯成多少个给出的n ...
- 1082: [SCOI2005]栅栏
链接 思路 二分+搜索+剪枝. 首先二分一个答案,表示最多可以切出x块.(一个结论:切出的一定是从较小的前x块.如果一个木材可以满足很多个需要的木材,那么切出最小的,就意味着以后再选时的机会更多.) ...
- [BZOJ1082][SCOI2005]栅栏 二分+搜索减枝
1082: [SCOI2005]栅栏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2430 Solved: 1034[Submit][Status ...
- bzoj1082: [SCOI2005]栅栏(二分答案搜索判断)
1082: [SCOI2005]栅栏 题目:传送门 题解: 是不是一开始在想DP?本蒟蒻也是qwq,结果很nice的错了ORZ 正解:二分+搜索 我们可以先把两种木材都进行排序,那么如果需要的最大木材 ...
- 【BZOJ1082】[SCOI2005]栅栏(搜索)
[BZOJ1082][SCOI2005]栅栏(搜索) 题面 BZOJ 洛谷 题解 随便写个爆搜,洛谷上就\(80\)分了.先放爆搜代码: #include<iostream> #inclu ...
- 洛谷 P2329 [SCOI2005]栅栏 解题报告
P2329 [SCOI2005]栅栏 题目描述 农夫约翰打算建立一个栅栏将他的牧场给围起来,因此他需要一些特定规格的木材.于是农夫约翰到木材店购买木材.可是木材店老板说他这里只剩下少部分大规格的木板了 ...
随机推荐
- 利用python实现简单随机验证码
#!/usr/bin/env python # -*- coding:utf-8 -*- import random temp ='' for i in range(6): num = random. ...
- slf4j 与 log4j2 基本用法
简单的说 log4j2 是log4j2的升级版,解决了部分性能问题和部分死锁问题,其使用方式与使用配置与log4j相同. 建议使用maven依赖直接使用log4j2 <dependency> ...
- JAVA_SE基础——14.循环结构语句
建议有些基础的同学阅读,0基础可能会有些困难(最好看正文配合基础课本的例子) 所谓循环语句主要就是在满足条件的情况下反复执行某一个操作.Java提供了3种常用的循环语句,分别为for循环语句.whil ...
- 简单介绍 CPU 的工作原理
1.内部架构 CPU 的根本任务就是执行指令,对计算机来说最终都是一串由 0 和 1 组成的序列.CPU 从逻辑上可以划分成 3 个模块,分别是控制单元.运算单元和存储单元 .其内部架构如下: [1] ...
- Linq 生成运算符 Empty,Range,Repeat
var c1 = Enumerable.Empty<string>();//c1.Count=0 , );//{9527,9528,9529,......9536} , );//{9527 ...
- 新概念英语(1-133)Sensational news!
Lesson 133 Sensational news! 爆炸性新闻! Listen to the tape then answer this question. What reason did Ka ...
- 访问器属性:setter()函数和getter()函数
1.干嘛用的? getter()函数:返回有效的值 setter()函数:调用它并传入数据,这个函数决定如何处理数据 2.具备哪些属性?如何定义? configurable(默认为true),enum ...
- spark2.1:flatMap的用法
代码示例: val sample_data_combine_result=List( (0,(List(FitModel(4022,1447.92,-8.38983306721434,2.0)),1) ...
- MongoDB的安装和使用指南
什么是MongoDB MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系 ...
- hdu1443 Joseph---约瑟夫环
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1443 题目大意: 一共有2k个人,分别为k个好人和k个坏人,现在我们需要每隔m个人把坏人挑出来,但是 ...