算法——尼克的任務

題目描述

尼克每天上班之前都連接上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由一個開始時刻與一個持續時間構成。 尼克的一個工作日爲N分鐘,從第一分鐘開始到第N分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完成,尼克可以任選其中的一個來做,而其餘的則由他的同事完成,反之如果只有一個任務,則該任務必需由尼克去完成,假如某些任務開始時刻尼克正在工作,則這些任務也由尼克的同事完成。如果某任務於第P分鐘開始,持續時間爲T分鐘,則該任務將在第P+T-1分鐘結束。 寫一個程序計算尼克應該如何選取任務,才能獲得最大的空暇時間。

輸入

輸入數據第一行含一個空格隔開的整數N和K(1≤n≤10000,1≤k≤10000),N表示尼克的工作時間單位爲分鐘,K表示任務總數。
接下來共有K行,每一行有兩個用空格隔開的整數P和T,表示該任務從第P分鐘開始,持續時間爲T分鐘,其中1≤P≤N,1≤P+T-1≤N。

輸出

輸出文件僅一行,包含一個整數,表示尼克可能獲得的最大空暇時間。

樣例輸入

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

樣例輸出

4

解題思路 

  1. 任務根據開始時間排序;
  2.  i 表示分鐘數,i 之前是未被處理的狀態;i 到 n 的最大空閒時間用f(i)表示;
  3. 從後向前處理,當開始時間大於時間 i ,該任務不被考慮;
  4. 當開始時間小於 i ,則比較 f(i) 和 f(i+p[i].time)的較大值,返回到 f(i)中。

完整代碼

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int mn = 1e4+10;
struct node{
	int start,time;
}p[mn];
int N,M;
int cmp(const node &a,const node &b){
	return a.start < b.start ;
}

int main(){
	cin>>N>>M;
	int f[mn]={0};
	for(int i = 1; i <= M;i++){
		cin>>p[i].start>>p[i].time;
	}
	sort(p+1,p+M+1,cmp);
	for(int i=N,j=M;i>=1;i--){
		while(j>=1&&p[j].start > i) j--;
		if(j>=1&&p[j].start == i){
			while(j>=1&&p[j].start==i){
				f[i]=max(f[i],f[i+p[j].time ]);
				j--;
			}
		}
		else f[i]=f[i+1]+1;
	}
	cout<<f[1]<<endl;
	return 0;
}

推薦文章

算法——Boyer–Moore–Horspool algorithm(翻譯版)

算法——簡單揹包問題

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章