题意
并排的车道,标号0-10000。其中有K个车道损坏,需要维修。
维修前需要将连续的相邻的M个车道封闭,比如:
M=3时,5号车道损坏,可以有3种选择,封闭3-5,或者4-6,或者5-7
如果损坏的车道靠的比较近,可以共用封闭的车道,比如:
M=4时,5号和7号车道损坏,可以选择封闭4-7,或者5-8。也可以封闭2-5加上7-10,但是这样封闭车道总数会变多。
给定K,M,损坏车道编号。
求需要封闭的道路最小值。
样例
输入:
1 5 -----K=1,M=5
4 --------4号损坏
输出:
5
输入:
6 3
13 4 7 11 5 55 -----------排好序是: 4 5 7 11 13 55
输出:
10 ---------------------------封4-7,11-13,53-55.
#include<stdio.h>
#define MIN(a,b) (a)<(b)?(a):(b)
#define MAX(a,b) (a)>(b)?(a):(b)
int rNo[10000];
int M, K;
int dp[10000][10000];
void input();
void sort_1(int* a, int start, int end);
void DP(int start, int end)
{
int i, j, k;
for (i=end;i>=start;i--)
{
for (j=i;j<=end;j++)
{
dp[i][j] = MAX(M, rNo[j]- rNo[i]+1);
for (k = i; k < j; k++)
{
dp[i][j] = MIN(dp[i][j], dp[i][k] + dp[k + 1][j]);
}
}
}
}
/*
1 5
4
6 3
13 4 7 11 5 55
7 2
1 3 5 7 9 11 13
*/
int main()
{
input();
sort_1(rNo, 0, K - 1);
int i, j, start, res;
start = res = 0;
for (i = 1; i < K; i++)
{
if (rNo[i] - rNo[i - 1] >= 2 * M - 1)
{
DP(start, i - 1);
res += dp[start][i - 1];
start = i;
}
}
DP(start, K - 1);
res += dp[start][K - 1];
}
void input()
{
int i = 0;
scanf("%d %d", &K, &M);
for (i = 0; i < K; i++)
{
scanf("%d", &rNo[i]);
}
}
void sort_1(int* a, int start, int end)
{
int i, j, tmp;
for (i = start; i < end; i++)
{
for (j = i + 1; j < end; j++)
{
if (a[i] > a[j])
{
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
}
}