pat頂級1002 Business (35 分)

歡迎訪問我的pat頂級題解目錄

題目描述

pat頂級1002 Business (35 分)題目描述

算法設計

這是一道0-1揹包問題。設PiP_iLiL_iDiD_i分別表示第ii個任務的收益、持續時間、截止日期,d(i,j)d(i,j)表示在第1,2,,i1,2,\dots,i個任務中,任選一些能夠在jj天內完成的任務,所得到的最大收益。假設下標從1開始。我們首先按截止日期從小到達對這些任務進行排序。我們要注意,如果在第jj天要完成第ii個任務,那麼這個任務的最晚開始時間應該是K=min(Di,j)LiK=min(D_i,j)-L_i,顯然當K<0K<0時,這個任務不可能在第jj天完成。那麼我們可以得到狀態轉移方程:

  1. K<0d(i,j)=d(i1,j)K<0,d(i,j)=d(i-1,j)
  2. K0d(i,j)=max{d(i1,j),d(i1,k)+Pi)K\geq0,d(i,j)=max\{d(i-1,j), d(i-1,k) +P_i)

C++代碼

#include <bits/stdc++.h>
using namespace std;
struct Pro {
    int p, l, d;
};
int main() {
    int n;
    cin >> n;
    vector<Pro> pros(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> pros[i].p >> pros[i].l >> pros[i].d;
        t = max(t, pros[i].d);
    }
    sort(pros.begin(), pros.end(), [](const Pro& p1, const Pro& p2) {
        return p1.d < p2.d;
    });
    int t = pros.back().d;
    vector<vector<int>> dp(n + 1, vector<int>(t + 1));
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= t; ++j) {
            dp[i][j] = dp[i - 1][j];
            int k = min(j, pros[i].d) - pros[i].l;
            if (k >= 0)
                dp[i][j] = max(dp[i][j], dp[i - 1][k] + pros[i].p);
        }
    }
    cout << dp[n][t];
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章