首页 > 其他分享 >p4801题解

p4801题解

时间:2023-10-10 18:23:49浏览次数:27  
标签:饼干 int 题解 long t1 p4801 num ws

解题思路:

确实是一道很好的贪心,但由于加上了这个影响因素,使题目复杂度上升了不少。(考虑的东西多了嘛)

  1. 输个入。
  2. 对饼干温度无脑排序。
  3. 求最小值。
  4. 求最大值(用双指针做,后面会讲)。

解题过程:

先输入(这个步骤就不用我讲了

int a[1000005];
    long long n,ws;
    long long minn=0,num=ws;
    cin>>n>>ws;//输入饼干数和水温
    for(int i=1;i<=n;i++)
        cin>>a[i];

先排序!!

sort(a+1,a+n+1);

最容易的肯定就是最小值

!其实题意一定要读懂,我个提醒也是我自己看错的:

每当他吃一块饼干时,这块饼干的美味度为当前饼干与吃/喝的前一样食物(包括饼干和水)的温度的差的绝对值。


  • 那我们不妨分三种情况来考虑(ws 是水温):
  1. 当水温小于等于饼干中温度的最小值,此时喝好水后,从饼干中最小值一直按顺序(单调升序,前面排好序了)吃到最大值 (\(a_1,a_2\cdots a_n\)) 就是累计美味值最小的。
if(ws<=a[1]){
    minn=a[n]-ws;
}
  1. 水温大于等于饼干中温度的最大值时,喝好水后,按单调降序 (\(a_n,a_{n-1}\cdots a_1\)) 吃掉饼干可获得最小值。则有:
if(ws>=a[n]){
	minn=ws-a[1];
}
  1. 当 \(a_1\le ws\le a_n\) 时,直接 \(a_n-a_1\) 即可:
if(ws>=a[1]&&ws<=a[n]){
	minn=a[n]-a[1];
}

那么接下来是最大值:

前面也提到了要用双指针做,具体怎么实现呢?

先定义两个指针:

t1=1;t2=n;

因为排好序后,\(a_n-a_1\) 的跨度最大,然后 \(a_1-a_{n-1}\),再是 \(a_{n-1}-a_2\cdots\),以此类推,两个指针依次向中间靠拢,就可算出最大的美味值和了。

但是此时要考虑两点:

  1. 喝好水后应该先吃 \(a_n\) 还是 \(a_1\)。
  2. 在双指针的过程中,判断是喝了水后吃下一个饼干的美味值大还是直接吃美味值大。

所以我们要循环两次,分别为先吃 \(a_1\) 和先吃 \(a_n\),并在过程中判断上面所说的第2点。

则有

   long long num=ws;//存储上一个食物的温度
   long long ans2=0,ans=0;//分别分析取a[1]与a[n]为开头的情况(找最优解);
	ans+=abs(ws-a[t1]);
	num=a[t1];//从a[1]开始
	t1++;
	for(int i=2;i<=n;i++){
		if(i%2==0){
			ans+=max(abs(num-a[t2]),abs(ws-a[t2]));
			num=a[t2];
			t2--;
		}
		else{
			ans+=max(abs(num-a[t1]),abs(ws-a[t1]));
			num=a[t1];
			t1++;	
		}
	}
	t1=1;t2=n;//从a[n]开始
	ans2+=abs(ws-a[t2]);
	num=a[t2];
	t2--;
	for(int i=1;i<=n-1;i++){
		if(i%2==0){
			ans2+=max(abs(num-a[t2]),abs(ws-a[t2]));
			num=a[t2];
			t2--;
		}
		else{
			ans2+=max(abs(num-a[t1]),abs(ws-a[t1]));
			num=a[t1];
			t1++;
		}
	}
	ans=max(ans2,ans);//赋值最优解

到这里题就做完了,那——

AC 代码!

#include<bits/stdc++.h>
using namespace std;
int a[1000005];
int main(){
	long long n,ws;
	cin>>n>>ws;//输入饼干数和水温
	long long minn=0,num=ws;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	sort(a+1,a+n+1);//排序!!!!
	long long cnt=1;
	long long t1=1,t2=n;
	if(ws<=a[1]){//判断最小值
    	minn=a[n]-ws;
	}
	else if(ws>=a[n]){
		minn=ws-a[1];
	}
	else{
		minn=a[n]-a[1];
	}
	long long ans2=0,ans=0;//判断最大值,分别分析取a[1]与a[n]为开头的情况(找最优解);
	ans+=abs(ws-a[t1]);
	num=a[t1];//存储上一个食物或水的温度
	t1++;
	for(int i=2;i<=n;i++){
		if(i%2==0){
			ans+=max(abs(num-a[t2]),abs(ws-a[t2]));
			num=a[t2];
			t2--;
		}
		else{
			ans+=max(abs(num-a[t1]),abs(ws-a[t1]));
			num=a[t1];
			t1++;	
		}
	}
	t1=1;t2=n;
	ans2+=abs(ws-a[t2]);
	num=a[t2];
	t2--;
	for(int i=1;i<=n-1;i++){
		if(i%2==0){
			ans2+=max(abs(num-a[t2]),abs(ws-a[t2]));
			num=a[t2];
			t2--;
		}
		else{
			ans2+=max(abs(num-a[t1]),abs(ws-a[t1]));
			num=a[t1];
			t1++;
		}
	}
	ans=max(ans2,ans);//取最优解
	cout<<minn<<" "<<ans;//华丽结束!
	return 0;
}

标签:饼干,int,题解,long,t1,p4801,num,ws
From: https://www.cnblogs.com/wyl123ly/p/p4801_sulotion.html

相关文章

  • 洛谷P4158 [SCOI2009] 粉刷匠 题解
    所有的\(DP\),只要式子一推出来(不管复杂度),那就很简单了,因为优化是成千上万种的……思路1:我们考虑设\(f[i][j][k]\)表示:当前\(DP\)到第\(i\)块木板的第\(j\)个位置,共涂了\(k\)次,所能获得的最大收益。因为还要枚举当前这次涂是从哪到哪的,因此复杂度为\(O(NM^2T)\),实......
  • 洛谷P3300 [SDOI2013] 城市规划 题解
    [SDOI2013]城市规划题意:给你一个\(6\timesn\)的网格题,单点修改,询问区间联通块数,\(n\le10^5\)。解:看起来就很显然的一道题......线段树每个点用一个ufs维护连通性;我为了方便思考把图转成横着的了。写起来真是毒瘤......重点在于:\(\bullet\)1、建立叶节点。\(\bull......
  • 【ABC320C】题解
    AtCoderBeginnerContest320ProblemC-SlotStrategy2(Easy)题解题目简述给定\(3\)个长度为\(m\)的转盘,转动过后三个转盘分别可以在不同的时间停下,求停下时所有转盘都显示相同数字的最小时间。思路由于这题\(m\le100\),数据较水,所以可以先把每个数列都复制\(......
  • 【ABC320D】题解
    AtCoderBeginnerContest320ProblemD-RelativePosition题解题目保证不矛盾,就可以直接vector建图,然后dfs一遍,边权为\((w_x,w_y)\)表示坐标的差,从\(u=1\)开始搜索,设点\(u,v\)有一条无向边,\(v_x=u_x+w_x,v_y=u_y+w_y\),最后如果没有被标记过的话(也就是没有......
  • 【题解】Fibonacci-ish II
    传送门题目分析根据题目范围\(n\le30000\)并且此题可以离线维护这个很恶心的东西,所以我们考虑莫队。由于要求访问到任意一个区间都要求知道它有序之后的序列,所以这个东西可以用权值线段树维护。因此,此题正解是莫队+权值线段树。我们分类讨论一下加上一个数,删除一个数对答案......
  • 题解 P3894【[GDOI2014] 传送】
    难倒不难,128MB的空间限制快恶心死我了。我们设\(d_{u_0,u_1}\)表示到节点\((u_0,u_1)\)距离最近的叶子的距离,这个可以很容易换根DP求出。设\(p_{u_0}\)表示树\(u_0\)中距离最近的两个叶子的距离。设\(dis(u_0,u_1,v_0,v_1)\)(\(u_0=v_0\))表示树中两个节点\(u_1\)和......
  • 【ABC322C】题解
    AtCoderBeginnerContest322ProblemC-Festival题解Meaning-题意简述给定\(N\)和\(M\),还有\(M\)个正整数\(a_1\sima_n\),对于每个\(i\len\),求出\(a\)中第一个大于等于\(i\)的整数和\(i\)的差。Solution-题解思路题目保证\(a\)数组单增,所以就可......
  • 【LG-P7617】题解
    题解思路不用关心每个数的每一位是什么、哪几位相同,我们只需记录每个数出现了哪几个数字,可以使用类似于状态压缩的思想记录每个数的状压形式,比如一个数为\((4)_{10}\),那么他的状态压缩形式为\((00001)_2\)。当两个数在状态压缩表示下有一位相同,我们就认为这两个数是一对,每个......
  • 【ABC322D】题解
    AtCoderBeginnerContest322ProblemD-Polyomino题解Meaning-题意简述给定三个字符矩阵,求它们能不能拼在一起变成一个\(4\times4\)的全部是#的矩阵。Solution-题解思路大模拟。说简单也不简单,很复杂;但是说难呢,又不难。思路:搜索每一个矩阵的状态。0x001旋......
  • P1220 关路灯 题解
    Description给定\(n\)个点的位置\(a_i\)和每秒的花费\(b_i\),你的初始位置是\(s\),你删掉一个点的时间为\(0\)秒,走\(1\)个单位长度的时间是\(1\)秒。请你确定一种关灯顺序,使得所有点的最终花费最小(删掉点后这个点不会再花费)。Solution每删掉一个点,有两种选择:继续往前......