圆形谷仓Circular Barn_Silver---(DP优化 / )队列 + 贪心(复杂度O(2n))---DD(XYX)的博客
目录
小数据
题目描述
农夫约翰有一个圆形的谷仓,谷仓分成了环形的n(3≤n≤1000)个房间,编号为1 , 2 , …… 。每个房间有三个门,两个门通往两个相邻的房间,第三个门朝外。约翰有n头奶牛,乱哄哄的在谷仓外面。有的房间门口有多头奶牛排队,有的房间外一头也没有。现在约翰想让每头奶牛都呆在一个房间,他要让奶牛先进入房间,然后按顺时针方向穿过门到其他的房间。奶牛的移动是要消耗能量的,一头奶牛经过 个门需要消耗 的能量。请问如何消耗最少的能量,完成约翰的任务。
输入
第一行包含n个整数,接下来n行,表示初始时每个房间的奶牛数,保证奶牛数等于n。
输出
一个整数,表示所需要的最小能量。
思路: 简单! 看这些 蒟蒻 人的就行: 洛谷题解
大数据
题目描述
农夫约翰有一个圆形的谷仓,谷仓分成了环形的n(3≤n≤100000)个房间,编号为1 , 2 , …… 。。。。。。(同上)
输入
第一行包含n个整数,接下来n行,表示初始时每个房间的奶牛数,保证奶牛数等于n。
输出
一个整数,表示所需要的最小能量。
思路
此题初看时,我就用了DP的思维,就是逆推。因为最终每个房间都会有一个奶牛,那么不妨用一个数组 来存每个房间的奶牛的出发地, 表示第 个房间的奶牛从第 个房间出发。首先把 初始化: = 。
然后就从任意一个房间开始,逆向循环,直到走完一圈后,遍历完 n 个房间。用一个队列 q ,依次存奶牛数为空的房间号,这样,q.front() 就会是顺时针方向的最远的空房间号。接下来,一旦遇到奶牛数 >1 的房间 , 就依次把多余的奶牛“移”到 q 队首的元素中,更新: 。如果 q 为空或者房间 奶牛数 = 1了,就停止。
如果 q 此时不为空,那就继续从(结束位置 - 1 )逆向循环,内容与之前完全相同,直到 q 为空。
为什么要把 i 房间的奶牛移到当前最远的位置 q.front() 呢?这是为了让后面的奶牛移动距离减短!
因为是距离 d 的平方,所以可以转化为面积:
明显第二种耗费能量最小。
最后循环一遍,根据每个奶牛的来源,计算能量总和。
最后别忘了转换成long long.