Big Event in HDU
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 9282 Accepted Submission(s): 3220
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).
A test case starting with a negative integer terminates input and this test case is not to be processed.
題目不難,不過是母函數還是DP,都搞不清了。
重點是通過這道題發現了 HDU 的 OJ 是先判輸出匹配再判主程序返回值的。
一開始,用的是小數組和庫函數 assert,連續 WA
// ...
assert (...);
static bool g [6000];
// ...
後來把庫函數 assert 換成自定義 Assert
void Assert (bool b) {
if (! b) {
while (true) {}
}
}
出現了 TLE。把數組開大點, AC 了。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
void Assert (bool b) {
if (! b) {
while (true) {}
}
}
void Solve () {
static int v [60]; // v of the problem
static int m [60]; // m of the problem
int n; // n of the problem
int total = 0;
if (scanf ("%d", &n) == EOF || n < 0) {
exit (0);
}
Assert (n < 60);
for (int i=0; i<n; ++i) {
scanf ("%d%d", &v[i], &m[i]);
total += v[i] * m[i];
}
int half = total / 2;
Assert (half < 150000);
static bool g [150000]; // generator
memset (g, 0, sizeof (g));
g [0] = true;
for (int i=0; i<n; ++i) {
for (int h=half; h>=0; --h) {
if (! g [h]) {
continue;
}
for (int k=1; k<=m[i] && h+k*v[i]<=half; ++k) {
g [h+k*v[i]] = true;
}
}
#ifdef _DEBUG
for (int h=0; h<=half; ++h) {
printf ("%d%s", g [h], h==half ? "\n" : " ");
}
#endif
}
int b = half + 1;
while (--b >= 0 && ! g [b]) {}
printf ("%d %d\n", total - b, b);
}
int main () {
while (true) {
Solve ();
}
return 0;
}