範例程式碼 uva709

//uva709
#include <iostream>
#include <string> 
using namespace std;

int main(){	
	int width;
	while(cin >> width && width){
		cin.ignore();
		
		string words[10050];
		int sumLength[10050];
		int dp[10050];
		int endWord[10050];
		
		string tmp;
		int wordCnt = 1;  // not use 0
		// read the paragraph
		while(getline(cin,tmp) && tmp.size() > 0){
			// split ( including a long space
			int begin = 0;
			int end = 0;
			while(end != -1){
				end = tmp.find(' ',begin);
				words[wordCnt] = tmp.substr(begin,end - begin);
				if(words[wordCnt].size() != 0) ++wordCnt;
				begin = end+1;
			}
		}
		
		// calculate the length after pick each word
		sumLength[0] = 0;
		for(int i = 1 ; i < wordCnt ; ++i)
			sumLength[i] = sumLength[i-1] + words[i].size();
		
		// dp from right to left
		dp[wordCnt] = 0;  // the dp initial state
		// calculate the best position to put each remaining word
		for(int i = wordCnt-1 ; i > 0 ; --i){  // i: curWord
			dp[i] = dp[i+1] + 500;  // penalty of one word occupying one line
			endWord[i] = i;         // start from words[i] ends at words[i]
			
			// try to pick in as more words as possible( ... B areBareactuallyBareactuallyconsidering.) 
			for(int j=i+1 ; j < wordCnt ; ++j){
				if(sumLength[j] - sumLength[i-1] + j - i > width) break;  // can not be a row (no space for ' ')
				int totalSpace = width - (sumLength[j] - sumLength[i-1]); // total extra space to fill
				int avgSpace = totalSpace / (j-i);                        // (average) middle space after between i to j words
				int extraSpace = totalSpace - avgSpace*(j-i);             // number of extra space
				// penalty of one row:  (number of avgSpace)*(length of space)^2 + (number of extra space)*(length of extra space)^2
				// length of space = midAvgSpace - 1 (that is, if midAvgSpace = 4, then penalty is 3^2)
				// length of extra space = midAvgSpace
				int cost = (j-i-extraSpace)*(avgSpace-1)*(avgSpace-1) + (extraSpace)*avgSpace*avgSpace;
				if( dp[i] >= dp[j+1] + cost ){
					dp[i] = dp[j+1] + cost;
					endWord[i] = j;    // start from words[i] ends at words[j]
				}
			}
		}
		
		// print the paragraph
		int curWord = 1;
		while(curWord < wordCnt){
			if(endWord[curWord] > curWord){
				int i = curWord;
				int j = endWord[i]/* - 1*/;
				int totalSpace = width - (sumLength[j] - sumLength[i-1]);
				int avgSpace = totalSpace / (j-i);
				int extraSpace = totalSpace - avgSpace*(j-i);
				
				int count = 0;         // how many avgSpace have been printed
				cout << words[i];      // start from words[i] ends at words[j]
				for(int nextWord = i+1 ; nextWord <= j ; ++nextWord){
					// print "avgSpace" space
					for(int space = 0 ; space < avgSpace ; ++space)
						cout << " ";
					if(++count > (j-i-extraSpace))
						cout << " ";
					cout << words[nextWord];					
				}
				cout << endl;
			}else{
				// if the word occupies one whole line
				cout << words[curWord] << endl;
			}
			curWord = endWord[curWord] + 1;
		}
		cout << endl;
		
	}
	return 0;
}