zoukankan      html  css  js  c++  java
  • 零件最大加工报酬问题

    用机器加工一批零件。每一个零件加工完可获得一定的加工报酬,并有加工时间要求:零件加工必须从某一时刻开始,到某一时刻结束,一次性连续加工完。
    零件的加工时间要求可能有冲突,但机器只有一台,在某个时刻,只能加工一个零件。一个零件开始时间和另一个零件结束时间相同不算冲突。
    请实现如下需求:在一批零件中,合理选择零件加工,输出满足上述条件的
    1)最大加工报酬。
    2)最优零件加工序列:能获得最大加工报酬的所有零件加工序列(可能有多组序列)

    说明: 
    每一个零件的信息包括:零件编号,零件加工报酬,加工开始时间,加工结束时间。每个零件的零件编号不能重复。 
        示例:
            零件信息——
                      零件编号 零件加工报酬 加工开始时间 加工结束时间
                          1         10           1            2
                          2         15           5            6
                          3         20           4            6
                          4         15           1            5
                          5         20           4            6

    计算结果: 
    1)最大加工报酬:30

    2)最优零件加工序列: 有三个,分别是{1,3}、{1,5}、 {4,2}

    解法:

    typedef struct product
    {
    int id;
    int reward;
    int start_time;
    int end_time;
    }Product;

    Product P[N];

    本题可用动态规划来解,首先将各个零件依据零件的加工结束时间从大到小进行排序,然后定义一个数组r[N],其中r[i]为到第i个为止的最大报酬,

    则r[i]=max{r[j]+P[i].reward,0<=j<i,且第i个零件的加工时间和第j个零件的加工时间不重合},最后的最大报酬为max{r[i],0<=i<n},本题与数组的最长递增子序列有几分相似之处。

    为了求得最优零件加工序列需要用数组pre[N]保存满足r[i]=max{r[j]+P[i].reward,0<=j<i,且第i个零件的加工时间和第j个零件的加工时间不重合} 条件的零件。最后遍历r[N]一遍,找出满足r[i]==maxreward的零件的id并根据pre[N]数组,打印出最优零件加工序列。

    具体代码如下:

    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef struct product//零件信息
    {
    	int id;
    	int reward;
    	int start_time;
    	int end_time;
    }Product;
    bool comp(Product p1,Product p2);//零件排序依据
    bool overlap(Product p1,Product p2);//判段区间是否交叉
    void max_reward(Product *P,int n);//求最大报酬
    void print_path(int m,int *pre,Product *P);//打印最优序列
    int main()
    {
    	int n;
    	cin>>n;
    	Product *P=new Product[n];
    	int i;
    	for(i=0;i<n;i++)
    		cin>>P[i].id>>P[i].reward>>P[i].start_time>>P[i].end_time;
    	sort(P,P+n,comp);
    	max_reward(P,n);
    	delete []P;
    	return 0;
    }
    bool comp(Product p1,Product p2)
    {
    	return p1.end_time<p2.end_time;
    }
    bool overlap(Product p1,Product p2)
    {
    	if(p1.end_time <=p2.start_time||p2.end_time<=p1.start_time)
    		return false;
    	return true;
    }
    void max_reward(Product *P,int n)
    {
    	if(P==NULL||n<=0)
    		return;
    	int *r=new int[n];
    	int *pre=new int[n];
    	int i,j;
    	for(i=0;i<n;i++)
    		pre[i]=-1;
    	for(i=0;i<n;i++)
    	{
    		r[i]=P[i].reward;
    		for(j=0;j<i;j++)
    		{
    			if(!overlap(P[i],P[j])&&(r[i]<r[j]+P[i].reward))
    			{
    				r[i]=r[j]+P[i].reward;
    				pre[i]=j;
    			}
    		}
    	}
    	int maxreward=0x8fffffff;
    	for(i=0;i<n;i++)
    	{
    		if(r[i]>maxreward)
    			maxreward=r[i];
    	}
    	cout<<"The maximum reward is "<<maxreward<<endl;
    	int k=1;
    	for(i=0;i<n;i++)
    	{
    		if(r[i]==maxreward)
    		{
    			
    			cout<<k++<<" : ";
    			print_path(i,pre,P);
    			cout<<endl;
    		}
    	}
    	delete []r;
    	delete []pre;
    }
    void print_path(int m,int *pre,Product *P)
    {
    	if(m<0||pre==NULL||P==NULL)
    		return;
    	if(m==0)
    	{
    		cout<<P[m].id<<" ";
    		return;
    	}
    	print_path(pre[m],pre,P);
    	cout<<P[m].id<<" ";
    }

    时间复杂度为O(n^2),空间复杂度为O(n);

  • 相关阅读:
    友盟上报 IOS
    UTF8编码
    Hill加密算法
    Base64编码
    Logistic Regression 算法向量化实现及心得
    152. Maximum Product Subarray(中等, 神奇的 swap)
    216. Combination Sum III(medium, backtrack, 本类问题做的最快的一次)
    77. Combinations(medium, backtrack, 重要, 弄了1小时)
    47. Permutations II(medium, backtrack, 重要, 条件较难思考)
    3.5 find() 判断是否存在某元素
  • 原文地址:https://www.cnblogs.com/james1207/p/3303875.html
Copyright © 2011-2022 走看看