1002 Business (35 分)(C++)

As the manager of your company, you have to carefully consider, for each project, the time taken to finish it, the deadline, and the profit you can gain, in order to decide if your group should take this project. For example, given 3 projects as the following:

  • Project[1] takes 3 days, it must be finished in 3 days in order to gain 6 units of profit.
  • Project[2] takes 2 days, it must be finished in 2 days in order to gain 3 units of profit.
  • Project[3] takes 1 day only, it must be finished in 3 days in order to gain 4 units of profit.

You may take Project[1] to gain 6 units of profit. But if you take Project[2] first, then you will have 1 day left to complete Project[3] just in time, and hence gain 7 units of profit in total. Notice that once you decide to work on a project, you have to do it from beginning to the end without any interruption.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (≤50), and then followed by N lines of projects, each contains three numbers P, L, and D where P is the profit, L the lasting days of the project, and D the deadline. It is guaranteed that L is never more than D, and all the numbers are non-negative integers.

Output Specification:

For each test case, output in a line the maximum profit you can gain.

Sample Input:

4
7 1 3
10 2 3
6 1 2
5 1 1

Sample Output:

18

題目大意:現在有很多項目等着你做,每個項目給出他的獲益,耗時以及DDL。找到怎麼選擇項目,並安排,使得最終獲益最大。

解題思路:動態規劃

n爲項目個數

m爲總天數(爲最晚的那個截止日期)

dp[i][j]表示第j天能在前i個項目獲得的最大利潤,初始均爲0。

首先將項目按照ddl進行排序,現在對第 i 個項目,j 從第一天開始,如果可以在第 j 天結束做這個項目,那麼開始做個這項目的時間 t = (截止日期和 j 中較小的數)- 項目所需時間,則 t 大於等於 0 ,纔可以在第 j 天完成這個項目。

當 t >= 0 的時候,dp[i][j] = max(dp[i-1][j], dp[i-1][t]+第i個項目的利潤),簡單來講,就是兩種情況,一種不做項目 i ,那麼利潤爲第j天在前i-1中獲得的最大項目,即dp[i-1][j];另一種,做這個項目,但是因爲最晚是從第 t 天開始做這個項目,所以利用爲第t天在前i-1中獲得的最大項目 + 該項目的利潤,即dp[i-1][t]+v[i-1].p(代碼中v是從0開始的,所以第i個項目對應v[i-1])。

當 t < 0, 說明不可以在第j天內完成這個項目,所以dp[i][j] = dp[i-1][j]

#include <bits/stdc++.h>
using namespace std;
struct project{
    int p, L, d;
};
int main(){
    int n, m;
    scanf("%d", &n);
    std::vector<project> v(n);
    for(int i = 0; i < n; ++ i)
        scanf("%d %d %d", &v[i].p, &v[i].L, &v[i].d);
    //按截止日期進行排序
    sort(v.begin(), v.end(), [](project a, project b){return a.d < b.d;});
    m = v[n-1].d; //m爲最晚的截止日期
    vector<vector<int>> dp((n+1), vector<int>(m+1, 0));
    for(int i = 1; i <= n; ++ i)
        for(int j = 1; j <= m; ++ j){
            int t = min(j, v[i-1].d) - v[i-1].L; // 計算最晚開始i項目的日期
            //判斷是否能在第j天開始做任務i
            if(t >= 0)
                dp[i][j] = max(dp[i-1][j], dp[i-1][t] + v[i-1].p);
            else
                dp[i][j] = dp[i-1][j];
        }
    printf("%d", dp[n][m]);
}

 

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