bzoj1082: [SCOI2005]栅栏(二分答案搜索判断)
1082: [SCOI2005]栅栏
题目:传送门
题解:
是不是一开始在想DP?本蒟蒻也是qwq,结果很nice的错了ORZ
正解:二分+搜索
我们可以先把两种木材都进行排序,那么如果需要的最大木材比可提供的最大木材还要大的话,那么可以直接舍弃这种需要的木材。
然后就可以进入二分,如果当前可以做贡献的提供木材加起来都没有前mid块需要木材大的话,很明显当前mid不ok
返回判断值再记录答案就好了,注意一些小细节的优化
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
typedef long long LL;
using namespace std;
bool flag;
int n,m,mid;
int a[],b[],bl[];
LL sa;
int sb[];
void dfs(int ak,int bk,int w)
{
if(bk==)flag=;
while(ak<=n && a[ak]<b[]){w+=a[ak];ak++;}//当前木材比最小的需求值还要小,跳下一个木材
if(flag || ak>n)return;//如果已经合法或者没有符合要求的木材了就退出(因为已经排序过了啊)
if(w+sb[mid]>sa)return;//如果有贡献的提供木材加起来都没有前mid块需要木材大,肯定不ok
int t=ak,t1=ak,t2=bk,t3=w;
if(b[bk]==b[bk+] && bk!=mid)t=bl[bk+];//小剪枝,如果我当前需要的木块和上一块一样,直接跳到上一次使用过的木材
for(int i=t;i<=n;i++)
if(a[i]>=b[bk])
{
bl[bk]=i;a[i]-=b[bk];
bk--;
dfs(ak,bk,w);
ak=t1;bk=t2;w=t3;a[i]+=b[t2];
}
}
int main()
{
scanf("%d",&n);for(int i=;i<=n;i++)scanf("%d",&a[i]);
scanf("%d",&m);for(int i=;i<=m;i++)scanf("%d",&b[i]);
sort(a+,a+n+);sort(b+,b+m+);
while(b[m]>a[n])m--;//如果需要的最大木材比可提供的最大木材还要大,舍弃,直接m--
int tot=;
for(int i=;i<=n;i++)if(a[i]>b[])a[++tot]=a[i];
n=tot;
for(int i=;i<=n;i++)sa+=a[i];
for(int i=;i<=m;i++)sb[i]=sb[i-]+b[i];
int l=,r=m,ans=;
while(l<=r)
{
mid=(l+r)/;
flag=;
dfs(,mid,);
if(flag!=)ans=mid,l=mid+;
else r=mid-;
}
printf("%d\n",ans);
return ;
}
bzoj1082: [SCOI2005]栅栏(二分答案搜索判断)的更多相关文章
- [BZOJ1082][SCOI2005]栅栏 二分+搜索减枝
1082: [SCOI2005]栅栏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2430 Solved: 1034[Submit][Status ...
- bzoj1082[SCOI2005]栅栏
Description 农夫约翰打算建立一个栅栏将他的牧场给围起来,因此他需要一些特定规格的木材.于是农夫约翰到木材店购 买木材.可是木材店老板说他这里只剩下少部分大规格的木板了.不过约翰可以购买这些 ...
- BZOJ1082: [SCOI2005]栅栏 题解
题目大意: 有一些木材,可以没有浪费地将一根木材分成几块木板(比如长度为10的木板可以切成长度为8和2的两块木板).现在你希望得到一些长度的木板,问通过分割木材最多能得到几块想要的木板. 思路: 首先 ...
- [SCOI2005]栅栏 二分+dfs
这个题真的是太nb了,各种骚 二分答案,肯定要减最小的mid个,从大往小搜每一个木板,从大往小枚举所用的木材 当当前木材比最短的木板还短,就扔到垃圾堆里,并记录waste,当 waste+sum> ...
- [luogu2329 SCOI2005] 栅栏(二分+搜索)
传送门 Solution 纯搜索80分,加二分90分,再补一个小剪枝满分qwq 真.小剪枝:如果下一个的需求和当前相同,那么不需要再次从头开始试(看代码就明白了233) Code #include & ...
- 【BZOJ 1082】[SCOI2005]栅栏 二分+dfs
对于最优解我们发现所有的最优解都可以是前多少多少个,那么我们就二分这个前多少多少个,然后用dfs去判解,我们发现在dfs的过程中如果不剪枝几乎必T,所以我们就需要一些有效的剪枝 I. 我们在枚举过程中 ...
- CF 371C-Hamburgers[二分答案]
C. Hamburgers time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...
- 【二分答案】 【POJ3497】 【Northwestern Europe 2007】 Assemble 组装电脑
Assemble Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3171 Accepted: 1013 Descript ...
随机推荐
- 2015.05.18,外语,学习笔记-《Word Power Made Easy》 03 “如何谈论不同从业者”
Prefix Person,nous,etc. Practice,etc. Adjective psyche 精神 psychic ['saikik] adj.精神的n.灵媒 -logos 科研 ps ...
- Qt-信号和槽-1对1
前言:信号和槽是Qt的核心机制,窗体和控件对象之间的沟通一般都使用信号和槽. 对于部件有哪些信号和槽,可以查看help文档. 一.使用自定义槽 1.1 新建工程 新建工程,新建Widget类(基于QW ...
- jquery 登录,删除提示信息框
<a onclick="return confirm('确认要退出登录吗?')">退出</a> //删除,修改,添加时提示信息框 (del,edit,add ...
- LinrFont UWP 字体预览工具下载
Windows 10 用户 购买 https://www.microsoft.com/zh-cn/p/linrfont/9nkh5mlvt819
- Java之Foreach语句
Foreach是for语句的特殊简化版本,但任何时候的foreach语句都可以改写成for语句.Foreach语句在遍历数组等方面为程序员提供了很大的方便 语法如下: For(元素变量 x:遍历对象o ...
- hdu 1080 dp(最长公共子序列变形)
题意: 输入俩个字符串,怎样变换使其所有字符对和最大.(字符只有'A','C','G','T','-') 其中每对字符对应的值如下: 怎样配使和最大呢. 比如: A G T G A T G - G ...
- Oracle的分页查询及内联视图和函数处理
1.Oracle的分页常用方式: select * from(select * ,ROWNUM num from table where ROWNUM<=20 ) where num>0; ...
- TCP/IP 三次握手和HTTP过程
0 引言 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. 1 T ...
- what is udev?
如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Linux改变了几次策略.在Linux早期,设备文件仅仅是是一些带有适当的属性集的普通文件,它由mknod命令创建,文件存放在/dev ...
- PAT 天梯赛练习集 L2-022. 重排链表
题目链接:https://www.patest.cn/contests/gplt/L2-022 给定一个单链表 L1→L2→...→Ln-1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln-1→L ...