石子合併問題

石子合併問題

Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description

在一個圓形操場的四周擺放着n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2 堆石子合併成新的一堆,並將新的一堆石子數記爲該次合併的得分。試設計一個算法,計算出將n堆石子合併成一堆的最小得分和最大得分。
對於給定n堆石子,計算合併成一堆的最小得分和最大得分。

Input

輸入數據的第1行是正整數n,1≤n≤100,表示有n堆石子。第二行有n個數,分別表示每堆石子的個數。

Output

輸出數據有兩行,第1行中的數是最小得分,第2行中的數是最大得分。

Sample Input

4
4 4 5 9

Sample Output

43
54

//////OJ提交runtime error了  暫時還不知道爲什麼,但是思路以及輸出結果目前沒問題

#include<iostream>
#include<vector>
#define inf 0x3f3f3f3f
using namespace std;

int min(int a, int b) {
	return a < b ? a : b;
}
int main() {
	int n;
	int temp;
	vector<int> a;
	vector<int> b;
	vector<int> c;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> temp;
		a.push_back(temp);//求最小
		c.push_back(temp);//備份求最大
	}
	
	int mincnt = 0;
        if(n == 1){
            mincnt = maxcnt = a[0];
        }
	while (a.size() > 1) {
		for (int i = 0; i < a.size()-1; i++) {
			b.push_back(a[i + 1] + a[i]);
		}
		b.push_back(a[a.size() - 1] + a[0]);
		
		int min1 = inf;
		int flag;
		for (int i = 0; i < b.size(); i++) {
			if (min1 > b[i]) {
				min1 = b[i];
				flag = i;
			}
		}
		mincnt += min1;
		if (flag == a.size()) {
			a[0] = min1;
			a.erase(a.begin() + (a.size() - 1));
		}
		else {
			a[flag] = min1;
			a.erase(a.begin() + flag + 1);
		}
		vector <int>().swap(b); //清空b中內容
		
	}
	int maxcnt = 0;
	while (c.size() > 1) {
		for (int i = 0; i < c.size() - 1; i++) {
			b.push_back(c[i + 1] + c[i]);
		}
		b.push_back(c[c.size() - 1] + c[0]);
		
		int max1 = 0;
		int flag;
		for (int i = 0; i < b.size(); i++) {
			if (max1 < b[i]) {
				max1 = b[i];
				flag = i;
			}
		}
		maxcnt += max1;
		if (flag == c.size()) {
			c[0] = max1;
			c.erase(c.begin() + (c.size() - 1));
		}
		else {
			c[flag] = max1;
			c.erase(c.begin() + flag + 1);
		}
		vector <int>().swap(b);
		
	}
	cout << mincnt << endl;
	cout << maxcnt << endl;
	return 0;
}

 

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