2013腾讯编程马拉松初赛第〇场(3月20日) 吉哥系列故事——临时工计划---带权重的区间规划

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4502

思路:带权重的区间规划问题,先将每个job按照完成时间进行排序,然后建立状态转移方程:OPT[I]=max{OPT[i-1],OPT[P[i]]+w[j]};其中P[i]代表与job i兼容的最大job下标。

代码:

 

#include <iostream>                               

#include <algorithm>                              

#include <cstring>  

#include <cstdlib>       

#include <cstdio>                       

                              

using namespace std;                              

const int maxn=1005;                              

int p[maxn];                                      

int opt[maxn];                                    

struct job{                               

	int s,f;                                         

	int w;                                           

};

job njob[maxn];                                      

bool cmp(job a,job b)                             

{                                                 

	return a.f<b.f;                                  

}       

bool iscompatible(job a,job b){

	if(b.s>a.f || a.s>b.f)return 1;

	return 0;

}                                          

void cal_p(int cnt)                                      

{                                                 

     p[1]=0;

	 for(int i=cnt-1;i>1;i--)

	 {

 		int k=i-1;

 		while(k>0 && !iscompatible(njob[i],njob[k]))

 			k--;

 		p[i]=k;	

 	 }                                           

}                                                 

int main()                                        

{                                                 

	int t;

	scanf("%d",&t);                                          

	while(t--)                                       

	{                                                

		int m,n;                                       

		scanf("%d%d",&m,&n);  

		int cnt=1;                                   

		for(int i=0;i<n;i++)                            

		{                                               

			int sj,ej,wj;                                   

			scanf("%d%d%d",&sj,&ej,&wj);                            

			if(sj<=ej && ej<=m && sj>0)                    

			{                                              

				njob[cnt].s=sj;                                 

				njob[cnt].f=ej;                                 

				njob[cnt++].w=wj;                                 

			}                                                                                            

		}

		sort(njob+1,njob+cnt,cmp);

		cal_p(cnt);

		memset(opt,0,sizeof(opt));

		for(int i=1;i<cnt;i++)

		{

			opt[i]=max(opt[i-1],opt[p[i]]+njob[i].w);

		} 

		printf("%d\n",opt[cnt-1]);                                

	}  		                   

	return 0;                         

}                                                 


 

 

 

 

你可能感兴趣的:(编程)