算法-封闭的车道-DP

题意

并排的车道,标号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;
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值