zoukankan      html  css  js  c++  java
  • 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
    ",opt[cnt-1]);                                
    	}  		                   
    	return 0;                         
    }                                                 


     

  • 相关阅读:
    最长上升子序列问题总结
    Problem C
    Problem C
    Problem P
    Problem P
    Problem H
    Problem H
    Problem D
    Problem D
    Linux系统调用--getrlimit()与setrlimit()函数详解
  • 原文地址:https://www.cnblogs.com/aukle/p/3223816.html
Copyright © 2011-2022 走看看