問題 1255: [藍橋杯][算法提高]能量項鍊

題目鏈接:https://www.dotcpp.com/oj/problem1255.html

題目描述

在Mars星球上,每個Mars人都隨身佩帶着一串能量項鍊。在項鍊上有 N顆能量珠。能量珠是一顆有頭標記與尾標記的珠子,這些標記對應着某個正整數。並且,對於相鄰的兩顆珠子,前一顆珠子的尾標記一定等於後一顆珠子的頭標 記。因爲只有這樣,通過吸盤(吸盤是Mars人吸收能量的一種器官)的作用,這兩顆珠子才能聚合成一顆珠子,同時釋放出可以被吸盤吸收的能量。如果前一顆 能量珠的頭標記爲m,尾標記爲r,後一顆能量珠的頭標記爲r,尾標記爲n,則聚合後釋放的能量爲m*r*n(Mars單位),新產生的珠子的頭標記爲m, 尾標記爲n。
需要時,Mars人就用吸盤夾住相鄰的兩顆珠子,通過聚合得到能量,直到項鍊上只剩下一顆珠子爲止。顯然,不同的聚合順序得到的總能量是不同的,請你設計一個聚合順序,使一串項鍊釋放出的總能量最大。
例如:設N=4,4顆珠子的頭標記與尾標記依次爲(2,3) (3,5) (5,10) (10,2)。我們用記號◎表示兩顆珠子的聚合操作,(j◎k)表示第j,k兩顆珠子聚合後所釋放的能量。則第4、1兩顆珠子聚合後釋放的能量爲:
(4◎1)=10*2*3=60。
這一串項鍊可以得到最優值的一個聚合順序所釋放的總能量爲
((4◎1)◎2)◎3)=10*2*3+10*3*5+10*5*10=710。

輸入

第一行是一個正整數N(4≤N≤100),表示項鍊上珠子的個數。第二行 是N個用空格隔開的正整數,所有的數均不超過1000。第i個數爲第i顆珠子的頭標記(1≤i≤N),當i〈N時,第i顆珠子的尾標記應該等於第i+1顆 珠子的頭標記。第N顆珠子的尾標記應該等於第1顆珠子的頭標記。
至於珠子的順序,你可以這樣確定:將項鍊放到桌面上,不要出現交叉,隨意指定第一顆珠子,然後按順時針方向確定其他珠子的順序。

輸出

只有一行,是一個正整數E(E≤2.1*10^9),爲一個最優聚合順序所釋放的總能量

樣例輸入

4
2 3 5 10

樣例輸出

710

解題思路:

題意是每個珠子能獲得的能量是a[i-1]*a[i]*a[i+1],使用後珠子消失。求能獲得的最大能量。

應該比較好想的一點:最後留下最大的幾個相乘,所能獲得的能量也就越大。而一開始把大的使用的,就不能再後面獲取更多的能量了,所以應該從數字最小的開始釋放能量,直到只剩下一個珠子爲止,一共進行n-1次釋放。

我先用一個數組把原來的順序存下來,然後將原數組排序,之後從小到大遍歷原數組,在b數組中找到相同的數字後進行運算,之後把運算的這個數字消除,把該數字後面的每一個數字都向前移動一位即可消除該數字。

AC代碼:

#include <bits/stdc++.h>
using namespace std;
const int N = 120;
int a[N], b[N];
int main() 
{
	int n;
	while(scanf("%d", &n)!=EOF)
	{
		for(int i=0; i<n; i++) {
			scanf("%d", &a[i]);
			b[i] = a[i];
		}
		long long ans = 0;
		sort(a, a+n);
		int m = n; 
		for(int i=0; i<n-1; i++) {
			for(int j=0; j<m; j++) {
				if(a[i]==b[j]) {
					if(j==m-1) 
						ans+=b[j-1]*b[j]*b[0];
					else if(j==0)
						ans+=b[m-1]*b[j]*b[j+1];
					else ans+=b[j-1]*b[j]*b[j+1];
					for(int p=j; p<m-1; p++) {
						b[p] = b[p+1];
					}
					m--;
					break;
				}	
			}
		}
		printf("%lld\n", ans);
	}
	return 0;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章