poj1505 Copying Books
这题用的是dp, 他要求的是计算在这一排书中, 每个抄写员都要抄写这些书中得一部分连续的书。
这题的状态转移时:dist[i][j] = min(max(dist[i - 1][t], p[k](j>=k >=1+t)) ( i<= t < j); 其中i是第几个抄写员
,j是抄写员从第t本书抄到第j本书。dist[i][j], 是前i个抄写员共抄J本书,所用的最多时间。
所以最少本书,应该是dist[n][m];
View Code
#include<stdio.h>
#include<string.h>
#define maxn 502
int dist[maxn][maxn], n, m;
int value[maxn];
void init()
{
int i;
memset(dist, 0, sizeof(dist));
memset(value, 0, sizeof(value));
for (i = 1; i<= m; i++)
{
scanf("%d", &dist[0][i]);
dist[1][i] = dist[1][i - 1] + dist[0][i];
}
return;
}
void funs()
{
int i, j, k, min, num, temp;
for (i = 2; i<= n; i++)
{
for (j = i; j<= m; j++)
{
k = j;
min = dist[1][j];
num = 0;
while (k >= i)
{
num += dist[0][k];
k--;
temp = num > dist[i - 1][k]? num:dist[i - 1][k];
if (min >= temp) min = temp;
else
{
break;
}
}
dist[i][j] = min;
}
}
k = m;
i = n;
while (k > 0)
{
num = 0;
while (k >= i && num + dist[0][k] <= dist[n][m])
{
num += dist[0][k];
k--;
}
i--;
value[k + 1] = 1;
}
printf("%d", dist[0][1]);
for (i = 2; i<= m; i++)
{
if (value[i] == 1) printf(" /");
printf(" %d", dist[0][i]);
}
printf("\n");
return;
}
int main()
{
int count;
scanf("%d", &count);
while (count --)
{
scanf("%d%d", &m, &n);
init();
funs();
}
return 0;
}