码迷,mamicode.com
首页 > 其他好文 > 详细

蛋糕分层

时间:2019-05-26 15:56:48      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:binary   min   div   特征   区间   不同   http   变量   tps   

【难度分析】★★★★★
【题目描述】

蛋糕店刚好有对应上、中、下三层的三类蛋糕,大家知道多层蛋糕一般都是上层最小,中层其次,下层最大,不然蛋糕就不漂亮了。在知道每一种蛋糕的体积的前提下有多少符合条件的方案。 

【思路分析】
【不好的个人感觉】

看到这道题,就感觉是动态规划,题目不是说蛋糕层数的要求吗?可以从下往上的推,个人的第二个感觉是一道搜索题,然后就这么打着,样例过的,手推的数据也过的。没想到就QAQ了。

【暴力出奇迹

爆0之后,试了一下暴力,把每一种情况都考虑一遍,选最优值,这样时间复杂度是O(n^2)的。至少还有点分(虽然我没提交,但我知道啊)。个人感觉就是不对。emm,我想复杂了。

【计数】

其实计数就是暴力的优化,读入把数字存入下标(万幸没有负数,哈哈)。数据卡的刚刚好。然后与暴力一样,不停地从上往下(只希望不要挂了),找最优值。啊,果然对了(AC)。这相当于是正解了吧。

先附上代码:(此代码,不要copy谢谢)

#include<bits/stdc++.h> // 万能头 
using namespace std; // 空间定义 
long long n,m,k,x,a[3939],b[3939],c[3939],maxn1,maxn2,maxn3,ans,a1[514514];//定义变量 
int main() { //开始疯狂的操作 
	cin>>n>>m>>k; // 读入这些值 
	for(int i=1; i<=n; i++) {
		cin>>x; //读入 
		a[x]++; // 放入下标 
		maxn1=max(maxn1,x);//取最大值 
	}
	for(int i=1; i<=m; i++) {
		cin>>x; // 读入 
		b[x]++; // 放入下标 
		maxn2=max(maxn2,x); // 取最大值 
	}
	for(int i=1; i<=k; i++) {
		cin>>x; // 读入 
		c[x]++; // 放入下标 
		maxn3=max(maxn3,x); // 取最大值 
	}
	for(int i=1; i<=max(maxn3,maxn2); i++)
		c[i]=c[i-1]+c[i]; // 前缀处理 ,类似 dp 
	for(int i=1; i<=max(maxn1+1,maxn2+1); i++)
		a1[i]=a1[i-1]+a[i-1]; // 前缀处理 ,类似dp 
	for(int i=1; i<=maxn2; i++)
		ans+=(c[maxn3]-c[i])*b[i]*a1[i]; // 不停累积最优值 
	cout<<ans<<endl; // 输入 
	return 0; // 好习惯,别忘记了 
}//End; 
【正解】

老师后来讲了这道题目,原来正解是二分,我恍然大悟(我那个时候为啥没有想到呢?)。

我知道你们对二分有点糊涂。

我来给你们讲一讲。

二分

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

二分查找对这道题没有用,我们解决这道题的话,要用二分答案。

【二分答案】

【定义】

二分答案与二分查找类似,即对有着单调性的答案进行二分,大多数情况下用于求解满足某种条件下的最大(小)值。

技术图片

  • 何时可以使用“二分答案”

    不是任何题目都适合使用“二分答案”的,我Sam观察到一般有以下的一些特征:

  • A. 候选答案必须是离散的 ,且已知答案的范围是:[最小值min, 最大值max] (连续区间上不能进行二分操作)
  • B. 候选答案在区间[min,max]上某种属性一类一类的排列 (这样就能在此属性上进行二分操作 ),各个类别不交错混杂

 

【模板说明】

一定要先排序。

      可以把答案看成key , 一旦当前这个序列中的数(我是根据从小到大排序的)大于key ,则右端点(r)要等于中间值(我取中间值为(l+r)>> 1).否则就取左端点(l)要等于中间值。

从大到小同理.

 

【二分模板代码】(不同人写法不同)(这是我的模板)

    int check(int key){
    int l = 1,r = n;
    int mid;
    while(l<=r){
        mid = (l+r) >> 1;
        if(key > a[mid]) l = mid+1;
        else if(key < a[mid])r = mid-1;
        else return 1;
    }
    return 0;
}

介绍算法结束!

 

【将二分融入题目之中】

二分答案的使用可以在查找蛋糕的最优值时候使用。

其他一样。

代码就不放了。自己思考。。。。

End!

蛋糕分层

标签:binary   min   div   特征   区间   不同   http   变量   tps   

原文地址:https://www.cnblogs.com/wangshengjun/p/10926206.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!