Fence Repair (POJ 3253)

农夫约翰为了修理栅栏,要将一块很长的木板切割成N块。准备切成的木板长度为L1、L2、L3、、、LN,未切割前的木板长度恰好为切割后木板长度的总和。每次切断木板时,需要的开销为这块木板的长度。例如长度为21的木板要切成长度为5,8,8的三块木板。长度为21的木板切成长度为13和8的板时,开销为21。再将长度为5和8的板时,开销为13。于是合计开销是34。请求按照目标要求将木板切割完最小的开销是多少。

#include "iostream"
using namespace std;

typedef long long ll;
const int MAX_N = 20000;
int N = 3, L[MAX_N] = {8,5,8};

void solve() {
	ll ans = 0;
	//直到计算到木板为1块时为止
	while (N>1)
	{
		//求出最短的木板mii1和次短的木板mii2
		int mii1 = 0, mii2 = 1;
		if (L[mii1] > L[mii2]) swap(mii1,mii2);
		//找出最短板与次短板的坐标
		for (int i = 2; i < N;i++) {
			if (L[i]<L[mii1])
			{
				mii2 = mii1;
				mii1 = i;
			}
			else if (L[i]<L[mii2]) {
				mii2 = i;
			}
		}
		//将两块板拼合
		int t = L[mii1] + L[mii2];
		ans += t;
		/*
			最短板恰好为最后一个板,则交换最短板与次短板坐标,目的让
			合成板放在较前位置覆盖掉,次短板交换最后一个板子,并且N-1
			如果次短板是最后一个板子则直接N-1被撇除。
		*/
		if (mii1 == N - 1)	swap(mii1,mii2);
		L[mii1] = t;
		L[mii2] = L[N-1];
		N--;
	}
	cout << ans << endl;
}
int main() {
	solve();
	system("pause");
	return 0;
}

 

posted @ 2016-06-18 13:41  sky-zz  阅读(235)  评论(0编辑  收藏  举报