用C++语言解决下面问题: 题目描述 带时限的作业排序问题可描述为:设有n个作业和一台处理机,每个作业所需的处理时间、要求的时限和收益可用三元组(pi, di, ti),0<=i<n表示,其中,作业i的所需时间为ti,如果作业i能够在时限di内完成,将可收益pi,求使得总收益最大的作业子集J。 输入 第一行输入n(0<n<15)的值;第二行输入pi;第三行输入di;第四行输入ti (i=0,…,n-1且作业已经按时限非减次序排列)。 输出 xi(用固定长度n-元组xi表示,xi=0或1,i=0,…,n-1),每个xi后带有一个空格。 样例输入 4 5 3 6 10 1 1 2 3 1 1 1 2 样例输出 0 0 1 1
时间: 2024-03-15 17:47:02 浏览: 74
以下是用 C++ 语言解决带时限的作业排序问题的代码:
```c++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Job {
int p, d, t;
};
bool cmp(const Job& a, const Job& b) {
return a.d < b.d;
}
int main() {
int n;
cin >> n;
// 输入作业的处理时间、时限和收益
vector<Job> jobs(n);
for (int i = 0; i < n; i++) {
cin >> jobs[i].p;
}
for (int i = 0; i < n; i++) {
cin >> jobs[i].d;
}
for (int i = 0; i < n; i++) {
cin >> jobs[i].t;
}
// 按照时限从小到大排序
sort(jobs.begin(), jobs.end(), cmp);
// 动态规划求解最大收益
vector<vector<int>> dp(n+1, vector<int>(n+1));
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dp[i][j] = dp[i-1][j];
if (j >= jobs[i-1].t && j <= jobs[i-1].d) {
dp[i][j] = max(dp[i][j], dp[i-1][j-jobs[i-1].t] + jobs[i-1].p);
}
}
}
// 输出最大收益和作业子集J
cout << dp[n][n] << endl;
vector<int> x(n);
int j = n;
for (int i = n-1; i >= 0; i--) {
if (j >= jobs[i].t && dp[i+1][j] == dp[i][j-jobs[i].t] + jobs[i].p) {
x[i] = 1;
j -= jobs[i].t;
}
}
for (int i = 0; i < n; i++) {
cout << x[i] << " ";
}
cout << endl;
return 0;
}
```
代码中,首先按照时限从小到大排序输入的作业,然后使用动态规划求解最大收益。dp[i][j] 表示前 i 个作业在 j 时间内完成的最大收益。对于第 i 个作业,如果它能够在时限内完成,那么可以选择将它放入作业子集,此时收益为 dp[i-1][j-jobs[i-1].t] + jobs[i-1].p;如果不将它放入作业子集,那么收益为 dp[i-1][j]。最终输出最大收益和作业子集J。
阅读全文