題目:
思考:
定義
(1)extra為行末多餘空白字元個數的立方和
(2)f[i,j] = M - j + i - SUM(lk) , i<=k<=j
(3)令len[i,j]表示第i個單詞到第j個單詞可以得到的最小extra
整齊列印問題可以分解成以下子問題
(1)若f[i,j] < 0,,則len[i,j] = MIN(len[i,k] + len[k+1,j]) , i<=k<j
(2)若f[i,j] > 0 && j==n,則len[i,j] = 0
(3)若i==j,則len[i,j] = (f[i,j])^3
代碼:為了編程方便,程式和說明略有不同
#include <iostream>#include <cmath>using namespace std;#define M 10//一行的最大長度#define N 10//單詞的個數int s[N][N];void DP(int *len){int i, j, k, step, temp;for(step = 0; step < N; step++){for(i = 0; i < N; i++){temp = 0;j = i + step;if(j >= N)break;//計算len[i,j]for(k = i; k <= j; k++){if(k != i) temp++;temp = temp + len[k];if(temp > M)break;}if(temp > M)s[i][j] = 0x7fffffff;//若f[i,j] > 0 && j==n,則len[i,j] = 0else if(j == N-1)s[i][j] = 0;//若i==j,則len[i,j] = (f[i,j])^3else s[i][j] = pow(M*1.0-temp,3);//若f[i,j] < 0,,則len[i,j] = MIN(len[i,k] + len[k+1,j]) , i<=k<jfor(k = i; k < j; k++)if(s[i][k]+s[k+1][j] < s[i][j])s[i][j] = s[i][k]+s[k+1][j];}}cout<<s[0][N-1]<<endl;}void Print(){int i, j;for(i = 0; i < N; i++){for(j = 0; j < N; j++)cout<<s[i][j]<<' ';cout<<endl;}}/*1 2 3 1 2 3 1 2 3 1*/int main(){int len[N], i;//輸出資料for(i = 0; i < N; i++)cin>>len[i];DP(len);//Print();return 0;}