带有期限的作业排序java实现

贪心方法的一个实例。问题大概就是处理n个作业,每个作业都有完成期限(Deadline),要求安排作业序列使效益达到最大。

算法的实现书上给了两种,一种是根据期限挨个插入,一种利用了树的思想。本文给出了第一种的java实现。

首先必须按效益从大到小把作业排序,当然对应的D数组也对应排好。依次将作业加入到集合J中,如果不违反任何已存在与J中的作业完成期限即可插入该作业。这个方法非常直观,因此即使复杂度比树方法稍高,我也更倾向于这种方法。

算法实现如下:

    public static int[] job(int[] D){
        int[] j=new int[D.length];
        j[0]=0;j[1]=1;
        D[0]=0;

        for(int i=2;i<D.length;i++)
        {
            int r=i;
            while(D[i]<D[j[r-1]] && D[j[r-1]]>r-1)
                r=r-1;              

            if(D[j[r-1]]<=D[i] && D[i]>=r)
            {
                for(int k=i-1;k>=r;k--)
                    j[k+1]=j[k];
                j[r]=i;

            }

        }
        return j;
    }

显然D已经根据P集合排好序了。由于涉及到作业标号,把D的大小设置为作业数加一。

直接把排序也放上

public void bubble(int[] x,int[] y){
        for(int i=0;i<x.length-1;i++)
            for(int j=i;j<x.length-1;j++)
                if(x[j]<x[j+1])
                {
                    int temp=x[j];
                    x[j]=x[j+1];
                    x[j+1]=temp;

                    int temp1=y[j];
                    y[j]=y[j+1];
                    y[j+1]=temp1;
                }
    }

x是效益数组,y是期限数组。

可以使用优先队列来实现期限作业排序问题。具体实现方法是将作业按照期限从小到大排序,然后将每个作业期限作为优先级,将作业依次加入优先队列中。当有新的作业加入时,如果当前队列中的作业数量已经超过了期限,则将队列中期限最大的作业删除,然后将新的作业加入队列中。最后,依次输出队列中的作业即可。 以下是示例代码: ``` #include <iostream> #include <queue> #include <vector> #include <algorithm> using namespace std; struct Job { int id; // 作业编号 int deadline; // 期限 int profit; // 收益 }; bool cmp(const Job& a, const Job& b) { return a.deadline < b.deadline; } int main() { int n; // 作业数量 cin >> n; vector<Job> jobs(n); for (int i = 0; i < n; i++) { cin >> jobs[i].id >> jobs[i].deadline >> jobs[i].profit; } // 按照期限从小到大排序 sort(jobs.begin(), jobs.end(), cmp); priority_queue<int, vector<int>, greater<int>> pq; // 小根堆,存储当前最优解 int max_profit = 0; for (int i = 0; i < n; i++) { if (pq.size() < jobs[i].deadline) { // 当前队列中的作业数量未超过期限 pq.push(jobs[i].profit); max_profit += jobs[i].profit; } else if (pq.top() < jobs[i].profit) { // 当前作业的收益大于队列中最小的收益 max_profit += jobs[i].profit - pq.top(); pq.pop(); pq.push(jobs[i].profit); } } cout << "最大收益:" << max_profit << endl; return 0; } ``` 该算法的时间复杂度为 O(nlogn),其中 n 为作业数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值