http://poj.org/problem?id=1014
参考了http://poj.org/showmessage?message_id=173435
完整代码:
/*0ms,376KB*/
#include<cstdio>
#include<cstring>
const int mx = 7;
const int mxw = 1300;
int m[mx], dp[mxw], deq[mxw], deqv[mxw];
int solve(int maxw, int n)
{
memset(dp, 0, sizeof(dp));
int i, a, j, s, t, val;
for (i = 1; i <= n; ++i)
for (a = 0; a < i; ++a)///枚举a=j%i
{
s = t = 0; ///deque的头和尾
for (j = 0; j * i + a <= maxw; ++j)
{
val = dp[j * i + a] - j * i;///划归为可重复使用的值
while (t > s && deqv[t - 1] <= val) --t;///保证deque的队首是最大的
deq[t] = j;
deqv[t++] = val;
dp[j * i + a] = deqv[s] + j * i;///从双端队列的头部取出最大值
if (deq[s] == j - m[i]) ++s;///这一头部已无法使用
}
}
return dp[maxw];
}
int main()
{
int i, sum, cas = 0;
while (scanf("%d%d%d%d%d%d", &m[1], &m[2], &m[3], &m[4], &m[5], &m[6]), m[1] || m[2] || m[3] || m[4] || m[5] || m[6])
{
printf("Collection #%d:\n", ++cas);
sum = 0;
for (i = 1; i <= 6; ++i)
{
if (m[i] > 60) m[i] = 60 + (m[i] & 1);
sum += i * m[i];
}
if (sum & 1) puts("Can't be divided.");
else
{
sum >>= 1;
puts(solve(sum, 6) == sum ? "Can be divided." : "Can't be divided.");
}
putchar(10);
}
return 0;
}