蓝桥杯训练题1255: [蓝桥杯][算法提高]能量项链【找规律,寻找最优情况,然后利用一维数组和二维数组进行相应乘和加操作算出答案】

题目链接:

https://www.dotcpp.com/oj/problem1255.html

题目大意:

先是给你一个数字N,代表后面有几个数字,然后每个数字和这个数字后面一位,两个整体看做成一个能量珠,其实就是一个二维数组啦。然后如果这个数字是最后面一位的话,那么这位数字的后面一位就认为是第1位,就相当于是把这个数字看成两个数字地圈。然后圈号的数字按照下面的规则去依次乘积,算出所有乘积最大的和。
比如:题目给的:N=4,
然后后面四个数字分别是:2,3,5,10
那么我们就可以得到相对应的四个珠:{2,3},{3,5},{5,10},{10,2}
*************************************珠: ①、 ②、、③、、④
然后需要我们这样乘:比如:我们让①和②合并,那么就是得到:这个值为:2×3×5,然后得到一个新的珠,为{2,5},我们称为⑤号珠。就是按照这种方式一直找下去,一直合并到一个珠为止,当然其中的值是需要记录的。

然后嘞,就是让我们找到一种最佳的合并方式使得珠合并产生的总值最大化,并且让我们输出这个值。

那么这个{2,3},{3,5},{5,10},{10,2}的最大化合并方式就是:
((④×①)×②)×③ = 10×2×3 + 10×3×5+10×5×10=60+150+500=710

思路:

首先就是先将这些数字用个一维数组val[105]给存起来也就是上面说到的这个“2,3,5,10”
然后通过val数组来构造出相对应的能量珠,而其中的值就用二维数组num[105][2]来存储也就是这个“{2,3},{3,5},{5,10},{10,2}”。
然后我们会发现,一维数组里的值在二维数组里面都会出现两次。然后,我们可以看到,只要我们将二维数组里的数按照一维数组里最小的值给消掉,那么剩下的数再去乘,这样可定时最优的。
那么也就是说我们消得顺序只要按照一维数组从小到大地顺序来就可以了。
比如:
N = 4,
5 6 3 4.
这个构造出来的一维数组为{5,6,3,4},
二维数组为{{5,6},{6,3},{3,4},{4,5}},
然后需要将一维数组排下序变为:{3,4,5,6}
①那么就先消3咯,找到二维数组中含有3的,即{6,3},{3,4},算出值:6×3×4=72,二维数组也随之变为{{5,6},{6,4},{0,0},{4,5}},
②再消4:找到二维数组有4的,即{6,4},{4,5}算出值为:6×4×5=120,二维数组也随之变为{{5,6},{6,5},{0,0},{0,0}},
③再消5:找到5的即:{6,5},{5,6}值变为:6×5×6=180
输出最终值ans=①+②+③=72+120+180=372
蓝桥杯训练题1255: [蓝桥杯][算法提高]能量项链【找规律,寻找最优情况,然后利用一维数组和二维数组进行相应乘和加操作算出答案】_第1张图片

ac代码:

#include 
 

typedef long long ll;

int n;
int val[105];
int num[105][2];//用来存储对应能量珠的前后值 
ll ans;//记录最后的答案 
void init(){//初始化二维数组即:初始化能量珠的值 
	int next;
	for(int j = 1;j <= n;j++){
		next = j+1;
		if(next > n){
			next = 1;
		}
		num[j][0] = val[j];
		num[j][1] = val[next];
	}
}


void sort(){//给一维数组排序 
	int temp;
	for(int h = 1;h <= n-1;h++){
		for(int k = h+1;k <= n;k++){
			if(val[k] < val[h]){
				temp = val[k];
				val[k] = val[h];
				val[h] = temp;
			}
		}
	}
}

void solve(){//用来处理二维数组的合并,并且记录合并产生的值 
	int temp;
	int index;
	int temp2;
	for(int i = 1;i < n;i++){
		temp = -1;
		index = -1;
		temp2 = -1;
		for(int j = 1;j <= n;j++){
			if(num[j][0]==0){
				continue;
			}
			if(num[j][0] == val[i]){//二维数组中第一位与一维数组值相等 
				temp = num[j][1];
				if(index != -1){
					num[index][1] = num[j][1];
				}
				
				num[j][0] = 0;
				num[j][1] = 0;
			}
			if(num[j][1] == val[i]){//第二位与一维数组中的值相等 
				temp2 = num[j][0];
				index = j;
				if(temp != -1){
					num[j][1] = temp;
				}
			}
		}
		ans += temp*temp2*val[i];

	} 
	
}


int main(){
	scanf("%d",&n);
	for(int i = 1;i <= n;i++){
		scanf("%d",&val[i]);
	}
	init(); 
	sort();
	ans = 0; 
	solve();
	printf("%lld\n",ans);
	
	return 0;
} 

你可能感兴趣的:(蓝桥杯训练题1255: [蓝桥杯][算法提高]能量项链【找规律,寻找最优情况,然后利用一维数组和二维数组进行相应乘和加操作算出答案】)