用c语言写个程序,实现最佳工作序列算法:有N件工作,输入每件工作的费时、最后完成的期限及工作的价值,试求可能的一个完成工作序列,使价值和最大。
时间: 2024-09-09 12:15:08 浏览: 49
C语言课程设计——教师工作量管理系统
使用C语言实现最佳工作序列算法,可以通过动态规划(Dynamic Programming, DP)的方法来解决。这个问题实际上是一个经典的调度问题,称为0-1背包问题的变形。我们将工作按照价值与截止期限的比值进行排序,然后使用动态规划来寻找最优解。
以下是一个简化的示例代码,实现了根据工作费时、截止期限和价值来找出可能的一个完成工作序列,使得价值和最大:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int time; // 费时
int deadline;// 截止期限
int value; // 价值
} Job;
int compare(const void *a, const void *b) {
Job *job1 = (Job *)a;
Job *job2 = (Job *)b;
double r1 = (double)job1->value / job1->deadline;
double r2 = (double)job2->value / job2->deadline;
if (r1 > r2) return -1;
if (r1 < r2) return 1;
return 0;
}
int findMaxValue(Job jobs[], int n) {
// 对工作按照价值/期限比值降序排序
qsort(jobs, n, sizeof(Job), compare);
int max_value = 0;
int dp[n + 1][n + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dp[i][j] = 0;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
if (jobs[i - 1].time <= j) {
dp[i][j] = dp[i - 1][j - jobs[i - 1].time] + jobs[i - 1].value;
}
dp[i][j] = (dp[i][j] > dp[i - 1][j]) ? dp[i][j] : dp[i - 1][j];
}
}
// 回溯找出工作序列
int seq[n], l = n;
int m = n, sum = dp[n][n];
for (int i = n; i > 0; i--) {
if (sum == dp[i - 1][m]) {
l--;
} else {
seq[l--] = i - 1;
sum -= jobs[i - 1].value;
m -= jobs[i - 1].time;
}
}
printf("工作序列(从最后完成的工作开始): ");
for (int i = 0; i < n; i++) {
if (seq[i] != -1) {
printf("%d ", seq[i] + 1);
}
}
printf("\n总价值: %d\n", dp[n][n]);
return dp[n][n];
}
int main() {
int n;
printf("请输入工作的数量: ");
scanf("%d", &n);
Job jobs[n];
for (int i = 0; i < n; i++) {
printf("请输入第%d件工作的费时、最后完成的期限及工作的价值: ", i + 1);
scanf("%d %d %d", &jobs[i].time, &jobs[i].deadline, &jobs[i].value);
}
findMaxValue(jobs, n);
return 0;
}
```
这段代码首先定义了一个Job结构体来存储每件工作的相关信息,然后通过比较价值与截止期限的比值来对工作进行排序。接着使用动态规划计算出最大的价值和,并通过回溯找出对应的完成工作序列。最后在main函数中通过用户输入获取工作的具体信息,并调用findMaxValue函数来执行算法。
阅读全文