codeforces-1130B. Two Cakes-题解--(有点难)

题目:

B.两个蛋糕
Sasha和Dima想买两个n层蛋糕。每个蛋糕应该由n个不同的层组成。层应该按照从最小到最大的顺序排列(从上到下)。
他们住在同一条街上,有2⋅n房屋在一行从左到右。每个房子都有一个糕点店,你可以在那里买一个蛋糕层。不幸的是,在每家糕点店只能买到一层,而且只能买到一种特定尺寸的:在第ii家,可以买到一层尺寸为ai(1≤ai≤n)的糕点。
由于这些人携带已经购买的层,这是不可能插入一个新的层在蛋糕中间,他们同意购买层从最小的到最大的。也就是说,他们每个人都按顺序购买层:1层、2层、3层,一直到n。
最初,Sasha和Dima位于第一个(最左边)房子附近。输出购买两个蛋糕总共需要走的最小距离。相邻两幢房子之间的距离正好是1。
输入
输入的第一行包含一个整数n——每个蛋糕的层数(1≤n≤10^5)。
第二行包含2⋅n个整数a1, a2,…,an, (1≤ai≤n),在ai等于层的大小,在i-th可以买房子。记住,每栋房子只能买一层。保证从1到n的每一个数字在a中都精确地出现两次。
输出
打印一个数字——买两个蛋糕的人总共要走的最小距离。男人可以在同一时间靠近同一所房子。他们从第一个(最左边的)房子附近开始。每个人都应该按照他们的大小购买n层。
例子
input
3.
1 1 2 2 3 3
output
9
input
2
2 1 1 2
output
5
input
4
4 1 3 2 2 3 1 4
output
17


思路

题目翻译:两个人要做N层蛋糕,已知一条街上的商店每家只能提供一个x层蛋糕,输出两个人组装成n层蛋糕总共需要步行的最少步数。
题目思路:用vector记录每一层蛋糕的店家地址,形成一个二维数组。对于第一层和第二层蛋糕,就有两种组合方式,用点dp的思路往后推。另外要注意数组的初始化,要插入两个0

My code

#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
long long n,d[100005];
vector<long long> a[100005];//二维数组 
int main() 
{   
	//0  0                //输入4 
	//1  6                //4 1 3 2 2 3 1 4 
	//3  4 
	//2  5 
    //0  7 
	long long i,b,d1,d2; 	
	cin >>n; 
	for(i = 0;i<2*n;i++){ 
		cin >> b;        
		a[b].push_back(i);//将i放在第b行的尾部 
	}//二维数组里存的数字是表示步数 
	a[0].push_back(0);
	a[0].push_back(0);
	for(i = 1;i<=n;i++){
		d1 = abs(a[i][0] - a[i-1][0]) + abs(a[i][1] - a[i-1][1]);
		d2 = abs(a[i][0] - a[i-1][1]) + abs(a[i][1] - a[i-1][0]);
		d[i] = d[i-1] + min(d1,d2);
	} 
	cout<<d[n]<<endl;
	return 0;
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ OC保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/

 

posted @ 2019-03-12 23:34  金鳞踏雨  阅读(11)  评论(0编辑  收藏  举报  来源