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; }