尼克的任務~動態規劃

尼克的任務(0410)

Time limit(ms): 1000
Memory limit(kb): 65535
Submission: 1575
Accepted: 728
Didn't trying
尼克每天上班之前都連接上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由一個開始時刻與一個持續時間構成。
尼克的一個工作日爲N分鐘,從第一分鐘開始到第N分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完成,尼克可以任選其中的一個來做,而其餘的則由他的同事完成,反之如果只有一個任務,則該任務必需由尼克去完成,假如某些任務開始時刻尼克正在工作,則這些任務也由尼克的同事完成。如果某任務於第P分鐘開始,持續時間爲T分鐘,則該任務將在第P+T-1分鐘結束。
寫一個程序計算尼克應該如何選取任務,才能獲得最大的空暇時間。
Description
輸入數據第一行含一個空格隔開的整數N和K(1≤n≤10000,1≤k≤10000),N表示尼克的工作時間單位爲分鐘,K表示任務總數。
接下來共有K行,每一行有兩個用空格隔開的整數P和T,表示該任務從第P分鐘開始,持續時間爲T分鐘,其中1≤P≤N,1≤P+T-1≤N。
Input
輸出文件僅一行,包含一個整數,表示尼克可能獲得的最大空暇時間。
Output
1
2
3
4
5
6
7
15 6
1 2
1 6
4 11
8 5
8 1
11 5
Sample Input
1
4

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int dp[20000];//dp[i]表示如果當前在i分鐘,我能獲得的最大空閒時間
int n,k;
struct sta{
    int start;//開始時間
    int len;//持續時間
};
bool cmp(sta a, sta b)
{
    return a.start > b.start;
}
int main()
{
    while (cin >> n >> k)
    {
        sta data[20000] = { 0 };//儲存所有的工作
        memset(dp, 0, sizeof(dp));//默認每一分鐘剛開始空閒時間都是0  **
        for (int i = 0; i < k; i++)cin >> data[i].start >> data[i].len;//讀取所有工作
        sort(data, data + k,cmp);//工作表按開始時間由大到小排好序,好整理
 
        //從最後一組開始往前
        for (int i = n ,j= 0; i >= 1; i--)//i用於表示當前是多少分鐘,j用於標記當前工作時間表讀到哪一組了
        {
            if (i != data[j].start)dp[i] = dp[i + 1] + 1;//如果這一分鐘沒有工作的話,我能比下一分鐘多一分鐘的空閒
            else {
                //如果當前這一分鐘有工作
                while (data[j].start == i)//我就把所有當前時間的工作看一遍
                {
                    //第一次循環到這裏的時候,dp[i]還沒處理過,i分鐘的空閒時間還等於0  **
                    if (dp[i + data[j].len]>dp[i])//dp[i+data[j].len]表示如果我選擇當前這個工作,我的空閒時間和i+data[j].len分鐘後是一樣的,因爲在這期間我沒有增加空閒時間
                    {
                        //然後比較是我保存的dp[i]的空閒時間多,還是我接受這個工作能獲得的空閒時間更多
                        //第一次的時候,i時刻的空閒時間爲0,i+data[j].len時刻的空閒時間一定大於0,所以第一份工作是必須接受
                        //然後多次循環,比較後面的在i時刻開始的工作,尋找能獲得最大空閒時間的
                        dp[i] = dp[i + data[j].len];
                    }
                    j++;
                }
            }
        }
 
        cout << dp[1] << endl;
    }
    return 0;
}


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