Jackiesteed

www.github.com/jackiesteed

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

POJ_1093

源程序:

View Code
  1 //反向DP
2 #include <iostream>
3 #include <fstream>
4 #include <algorithm>
5 #include <cstring>
6 #include <cmath>
7 #include <climits>
8
9
10
11
12 using namespace std;
13
14 const int INF = INT_MAX;
15
16 char str[11000][100];
17 int dp[11000];
18 int path[11000];
19 int len[11000];
20 int sum[11000];
21 int N;
22 int cnt;
23 char tmp[1100];
24
25 bool check(int l, int c)
26 {
27 return l + c - 1 <= N;
28 }
29 int SQR(int x)
30 {
31 return x * x;
32 }
33 int w(int l, int c)
34 {
35 if(c == 1)
36 {
37 if(N == l)
38 return 0;
39 return 500;
40 }
41 int x = (N - l) / (c - 1);
42 int y = (N - l) % (c - 1);
43
44 int res = 0;
45 for(int i = 0; i < c - 1; i++)
46 {
47 if(y)
48 {
49 res += SQR(x);
50 y--;
51 }
52 else
53 res += SQR(x - 1);
54 }
55 return res;
56 }
57
58 void print(int s, int t)
59 {
60 int l = sum[t - 1] - sum[s - 1];
61 int c = t - s;
62 if(c == 1)
63 {
64 printf("%s\n", str[s]);//
65 //In the output, every line has to start and to end with a word.
66 //对于这句话,如果一行只用一个word,行尾不能有空格..
67
68 // printf("%s", str[s]);
69 // for(int i = 0; i < N - l; i++)
70 // putchar(' ');
71 // puts("");
72 // putchar('\n');
73 return ;
74 }
75 int x = (N - l) / (c - 1);
76 int y = (N - l) % (c - 1);
77 y = c - 1 - y;
78 for(int i = s; i < t; i++)
79 {
80 printf("%s", str[i]);
81
82 if(i == t - 1)
83 break;
84
85 if(y)
86 {
87 for(int j = 0; j < x; j++)
88 putchar(' ');
89 y--;
90 }
91 else
92 {
93 for(int j = 0; j < x + 1; j++)
94 putchar(' ');
95 }
96
97 }
98 puts("");
99 // putchar('\n');
100 }
101
102 int main()
103 {
104 // freopen("input.txt", "r", stdin);
105 // freopen("output.txt", "w", stdout);
106
107 while(true)
108 {
109 gets(tmp);
110 N = atoi(tmp);
111 if(0 == N)
112 break;
113
114 cnt = 0;
115 while(true)
116 {
117 gets(tmp);
118 if(0 == strlen(tmp))
119 break;
120 char * pch;
121 pch = strtok(tmp, " ");
122 while(pch != NULL)
123 {
124 strcpy(str[++cnt], pch);
125 pch = strtok(NULL, " ");
126 }
127 }
128 for(int i = 1; i <= cnt; i++)
129 {
130 len[i] = strlen(str[i]);
131 sum[i] = sum[i - 1] + len[i];
132
133 }
134
135 dp[cnt +1] = 0;
136
137 for(int i = 1; i <= cnt; i++)
138 dp[i] = INF;
139
140 for(int i = cnt; i >= 1; i--)
141 {
142 for(int j = i + 1; j <= cnt + 1; j++)
143 {
144 int l = sum[j - 1] - sum[i - 1];
145 if(check(l, j - i))
146 {
147 int tmp = w(l, j - i) + dp[j];
148 if(dp[i] >= tmp)//二,这个>= 很关键,本来倒着DP的目的就是为了是靠前的gap教小的?疏忽..
149 {
150 dp[i] = tmp;
151 path[i] = j;
152 }
153 }
154 else
155 {
156 break;
157 }
158 }
159 }
160 int x = 1;
161 while(x != cnt + 1)
162 {
163 print(x, path[x]);
164 x = path[x];
165
166 }
167 puts("");
168 }
169 return 0;
170 }

"In the output, every line has to start and to end with a word."

对于题目中这句话,当一行只用一个word,行尾是不能输出空格的.

POJ的数据没能检查出这个错误(对比ZOJ).

还有对于此题的PE的判断未免太宽松了,每行输出一个word都是PE..

不再举其他例子了,OJ大了难免有瑕疵,希望POJ越做越好.

posted on 2011-07-20 20:35  Jackiesteed  阅读(186)  评论(0编辑  收藏  举报