算法设计与分析:第四章 动态规划 4.6仪器维修时间表问题

/*
程序不是自己写的,需要仔细研究
一台精密仪器的工作时间为 n 个时间单位, 与仪器工作时间同步进行若干仪器维修程序. 一旦启动维修程序, 仪器必须进入维修程序. 如果只有一个维修程序启动, 则必须进入该维修程序. 如果在同一时刻有多个维修程序, 可任选进入其中的一个维修程序. 维修程序必须从头开始,不能从中间插入. 一个维修程序从第 s 个时间单位开始, 持续 t 个时间单位, 则该维修程序在第 s+t-1 个时间单位结束. 为了提高仪器使用率, 希望安排尽可能少的维修时间.  

对于给定的维修程序时间表, 计算最优时间表下的维修时间.

输入数据的第 1 行有 2 个小于 10000 的正整数 n 和 k, n 表示仪器的工作时间单位, k 是维修程序数. 接下来的 k 行中, 每行有 2 个表示维修程序的整数 s 和 t, 该维修程序从第 s 个时间单位开始, 持续 t 个时间单位.

Input  

15 6
1 2
1 6
4 11
8 5
8 1
11 5

Output  
11


*/
#include <stdio.h>
#define maxn 100
#define maxk 20
void insertsort(int s[],int t[],int n)
{
	int j;
	for(int i=1;i<n;i++)
	{
		int temp1=s[i];
		int temp2=t[i];
		j=i-1;
		while(j>=0&&s[j]>temp1)
		{
			s[j+1]=s[j];
			t[j+1]=t[j];
			j--;
		}
		s[j+1]=temp1;
		t[j+1]=temp2;
	}
}

int main(int argc, char *argv[])
{
	int n,k;
	int s[maxk],t[maxk];
	int i,j;
	int ans[maxn];
	int sum[maxk];
	scanf("%d%d",&n,&k);
	for(i=0;i<k;i++)
	{
		scanf("%d %d",&s[i],&t[i]);
	}
	insertsort(s,t,k);//插入排序,以s[i]进行排序,这样做是为了方便求最小值 
	for(i=n+1;i>=1;i--)
	{
		//若i大于最大的s[i]值,则m[i]等于0,因为没有维修任务 
		if(i>s[k-1])
			ans[i]=0;
		//其他值赋值为-1 
		else 
			ans[i]=-1;
	}
	// 遍历数组s[i],ans[x]表示x到n的最小维修时间 
	for(j=k-1;j>=0;j--)
	{
		//如果ans[x]没有计算过,则把第一次算到的值直接赋值给它
		//此时还要做的一步是把s[j]到s[j+1]的ans赋值为ans[s[j+1]]
		//这一段就相当于没有维修任务的时刻 
		if(ans[s[j]]==-1)
		{
			if(j!=(k-1))
			for(i=s[j]+1;i<s[j+1];i++)
				ans[i]=ans[s[j+1]];
			ans[s[j]]=ans[s[j]+t[j]]+t[j];
		}
		//若不为-1,则计算每次取最小值 
		else
		{
			if(ans[s[j]]>ans[s[j]+t[j]]+t[j])
				ans[s[j]]=ans[s[j]+t[j]]+t[j];
		}
	}
	//别忘了对0到s[0]的ans赋值 
	for(i=0;i<s[0];i++)
		ans[i]=ans[s[0]];
	printf("%d\n",ans[i]);
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值