UVA 10163 Storage Keepers

8443 단어 ora
UVA_10163
이 문제는 데이터 범위가 비교적 작기 때문에 처음에 내가 M*N*logP를 쓴 프로그램도 뛰어넘을 수 있다.먼저 2분의 1의 사고방식을 말해 보자. 우리는 각 창고의 안전치 하한선을 2분의 1로 나누고 최소 비용을 구할 수 있다.
나중에 다른 사람의 문제풀이 보고서를 본 후에 두 번 dp를 할 수 있다는 것을 발견했다. 첫 번째 dp는 가장 큰 안전치 하한선을 구하고 두 번째 dp는 이 하한선에 따라 가장 작은 비용을 구할 수 있다.
#include<stdio.h>
#include<string.h>
#define MAXN 110
#define MAXM 40
#define INF 0x3f3f3f3f
int N, M, P, f[MAXM][MAXN], p[MAXM];
int init()
{
int i, j;
scanf("%d%d", &N, &M);
if(!N && !M)
return 0;
P = 0;
for(i = 1; i <= M; i ++)
{
scanf("%d", &p[i]);
if(p[i] > P)
P = p[i];
}
return 1;
}
void solve()
{
int i, j, k, min, mid, max;
min = 0, max = P + 1;
for(;;)
{
mid = (min + max) / 2;
for(i = 1; i <= N; i ++)
f[0][i] = INF;
for(i = 0; i <= M; i ++)
f[i][0] = 0;
for(i = 1; i <= M; i ++)
for(j = 1; j <= N; j ++)
{
f[i][j] = f[i - 1][j];
for(k = 0; k < j; k ++)
if(p[i] / (j - k) >= mid && f[i - 1][k] + p[i] < f[i][j])
f[i][j] = f[i - 1][k] + p[i];
}
if(min == mid)
break;
if(f[M][N] == INF)
max = mid;
else
min = mid;
}
if(min == 0)
printf("0 0
");
else
printf("%d %d
", mid, f[M][N]);
}
int main()
{
while(init())
solve();
return 0;
}

 
#include<stdio.h>
#include<string.h>
#define MAXM 40
#define MAXN 110
#define INF 0x3f3f3f3f
int N, M, f[MAXM][MAXN],p[MAXM];
int init()
{
int i, j;
scanf("%d%d", &N, &M);
if(!N && !M)
return 0;
for(i = 1; i <= M; i ++)
scanf("%d", &p[i]);
return 1;
}
void solve()
{
int i, j, k, min, t;
for(i = 0; i <= M; i ++)
f[i][0] = INF;
for(i = 1; i <= N; i ++)
f[0][i] = 0;
for(i = 1; i <= M; i ++)
for(j = 1; j <= N; j ++)
{
f[i][j] = f[i - 1][j];
for(k = 0; k < j; k ++)
{
t = f[i - 1][k] < p[i] / (j - k) ? f[i - 1][k] : p[i] / (j - k);
if(t > f[i][j])
f[i][j] = t;
}
}
if(f[M][N] == 0)
{
printf("0 0
");
return ;
}
else
min = f[M][N];
for(i = 0; i <= M; i ++)
f[i][0] = 0;
for(i = 1; i <= N; i ++)
f[0][i] = INF;
for(i = 1; i <= M; i ++)
for(j = 1; j <= N; j ++)
{
f[i][j] = f[i - 1][j];
for(k = 0; k < j; k ++)
if(p[i] / (j - k) >= min && f[i - 1][k] + p[i] < f[i][j])
f[i][j] = f[i - 1][k] + p[i];
}
printf("%d %d
", min, f[M][N]);
}
int main()
{
while(init())
solve();
return 0;
}

좋은 웹페이지 즐겨찾기