ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

兼职 - Freelancer - 完全背包& (差分数组 or Indexed Tree)

2021-10-10 10:01:02  阅读:254  来源: 互联网

标签:10 日程 费用 int Tree Freelancer static Indexed 兼职


兼职

时限:最多 50 个用例,1 秒 (C/C++),1.5 秒 (Java)

 

S公司有N名全职员工。公司已经定制好了整个业务的工作日程,每位员工都被安排了工作,并且每个员工处理业务时,一次只能做一项工作。所以当业务日程重复了N次以上时,S公司就需要聘请兼职来工作。任何人都可以在中途接手另一个人的工作,这时的工作交接所耗费的时间和成本忽略不计。当聘请兼职时,如果同时跟多个人签订合约,那么提供兼职的公司会给予一定的费用折扣。

当给出了S公司的全职员工数量、整个业务日程,以及每日需要给兼职支付的费用信息时,想把兼职的雇用费用弄成最低。

 

 当给出如上所示的费用折扣信息时,如果S公司要聘请4个兼职,那么最优的方式是采用2 + 2,这时费用只需 38,000 韩元。如果业务日程信息如上所示,可以采用下面的方式开展工作。

如上所示,第1天需要1个人、第2天需要3个人、第3-4天需要4个人、第5天需要3人、第6天需要2个人、第7-8天需要1个人、第10-15天需要1个人。假设有2名全职员工,那么可以在第1、6-8、10-15天,只由全职员工处理业务,在第2天聘请1个兼职,费用为10,000韩元,在第3-4 天每天聘请2个兼职,费用为38,000韩元,在第5天聘请1个兼职,费用为10,000韩元。这样支付的就是最低兼职费用58,000韩元。

当给出S公司的全职员工数量、整个业务日程,以及每日给兼职支付的费用时,请找出给兼职支付的最少费用。

[限制条件]

1. 全职员工数量N为介于0到100,000之间的整数。

2. 业务日程数量M为介于1到200,000之间的整数。

3. 业务日程会给出开始日期和结束日期。如果日程之间的结束日期和开始日期之间有重合,则表示需要两个人。

4. 业务日程的开始日期S和结束日期E是介于1到100,000之间的整数.

5. 给兼职支付的费用C是介于10,000到100,000,000之间的整数。

6. 一个日程的业务能以一天为单位由多个人分工完成。

7. 任务安排完后,不应有多余的兼职。

8. 雇佣信息中一定会提供聘请一名兼职的费用。

[输入]

首先给出测试用例数量 T,接着给出 T 种测试用例。

每个测试用例的第一行空格区分给出全职员工数量N、业务日程数量M、给兼职支付费用的信息数量K。()

接下来通过M行,每行空格区分给出该业务日程的开始日期S和结束日期E。() 接下来通过K行给出聘请兼职时每天需要支付的费用信息,该信息空格区分给出人数P,需支付的费用C。()

 

[输出]

一个测试用例输出一行。对每个测试用例都输出“#x”(x为测试用例的编号,从1开始),然后输出S公司需要支付的最低兼职费用。

 

[输入和输出示例]

(输入)

3

2 5 5

1 5

2 8

3 6

10 15

2 4

1 10000

2 19000

5 47000

10 90000

150 1300000

1 10 5

1 10

9 10

3 9

6 10

10 10

6 9

3 7

1 6

7 7

1 10

1 10196

3 23895

4 29620

10 53460

15 57180

1 10 6

1 5

5 9

3 7

1 5

4 8

2 6

1 3

2 4

4 7

6 7

1 13354

2 23714

5 58520

10 111670

11 121319

17 185147

 

(输出)

#1 58000

#2 324280

#3 391248

 

解题思路:
如果先不考虑业务日程,求最小费用,每组折扣,可以选择多个,是个完全背包问题;
其中,费用种类总和K为物品数量,费用信息的每组人数为权重w[i],每组费用为物品价值v[i],业务日程数量M为背包容量;

求每天的工作需要的员工人数有两种方法:
1.差分数组
2.Indexed Tree, 用Indexed Tree时,query方法和update方法与平时的相反

 

package tree;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * 如果先不考虑业务日程,求最小费用,每组折扣,可以选择多个,是个完全背包问题;
 * 其中,费用种类总和K为物品数量,费用信息的每组人数为权重w[i],每组费用为物品价值v[i],业务日程数量M为背包容量;
 * 
 * 求每天的工作需要的员工人数有两种方法:
 * 1.差分数组
 * 2.Indexed Tree, 用Indexed Tree时,query方法和update方法与平时的相反
 * @author XA-GDD
 *
 */
public class Freelancer_0322 {
	static int T,N,M,K;
	static int _max_Nval = 100000;
	static int _max_Mval = 200000;
	static int _max_Kval = 100;
	static int [][] work = new int[_max_Mval+1][2];
	static int [][] fee = new int[_max_Mval+1][2];
	static long [] dp = new long[_max_Mval+1];
	static int [] empCnt = new int[_max_Nval+2];
	static int [] idxTree = new int[_max_Nval*4];
	static int offset;
	static long ANS;
	public static void main(String[] args) throws IOException {
		System.setIn(new FileInputStream("D:\\workspace\\sw_pro\\test_case\\sample_input_0322.txt"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	    StringTokenizer st = new StringTokenizer(br.readLine());
		T = Integer.parseInt(st.nextToken());
	    for(int testCase = 1; testCase<=T;testCase++) {
	    	st = new StringTokenizer(br.readLine());
	    	N = Integer.parseInt(st.nextToken());
	    	M = Integer.parseInt(st.nextToken());
	    	K = Integer.parseInt(st.nextToken());
	    	
	    	Arrays.fill(empCnt, 0);
	    	Arrays.fill(dp, 1,M,Long.MAX_VALUE);
	    	Arrays.fill(idxTree, 0);
	    	for(int i=0;i<K;i++) {
	    		Arrays.fill(fee[i], 0);
	    	}
	    	ANS=0L;
	    	
	    	//业务日程	
	    	int maxDate = 0;
	    	for(int i=0;i<M;i++) {
	    		st = new StringTokenizer(br.readLine());
	    		
	    		int startDate = Integer.parseInt(st.nextToken());
	    		int endDate = Integer.parseInt(st.nextToken());
	    		maxDate = Math.max(maxDate, endDate);
	    		
	    		
	    		//方法1:差分数组 ======start=========
//	    		empCnt[startDate]++;
//	    		empCnt[endDate+1]--;
	    		//方法1:差分数组 ======end=========
	    		
	    		//方法2:Indexed Tree ======start=========
	    		work[i][0] = startDate;
	    		work[i][1] = endDate;
	    		//方法2:Indexed Tree ======end=========
	    	}
	    	
	    	//方法1:差分数组 ======start=========
//	    	for(int i=1;i<=maxDate;i++) {
//	    		empCnt[i] += empCnt[i-1];
//	    	}
    		//方法1:差分数组 ======end=========
	    	
	    	//费用
	    	for(int i=0;i<K;i++) {
	    		st = new StringTokenizer(br.readLine());
	    		fee[i][0] = Integer.parseInt(st.nextToken());
	    		fee[i][1] = Integer.parseInt(st.nextToken());
	    	}
	    	
	    	//完全背包
	    	for(int i=0;i<K;i++) {
	    		for(int j=fee[i][0];j<=M;j++) {
	    			dp[j] = Math.min(dp[j], dp[j-fee[i][0]]+fee[i][1]);
	    		}
	    	}
	    	
	    	//方法1:差分数组 ======start=========
//	    	for(int i=0;i<=maxDate;i++) {
//	    		ANS += empCnt[i]>N? dp[empCnt[i]-N]:0;
//	    	}
	    	//方法1:差分数组 ======end=========
	    	
	    	
	    	//方法2:Indexed Tree ======start=========
	    	int k=0;
	    	while((1<<k)<maxDate) {
	    		k++;
	    	}
	    	offset=1<<k;
	    	for(int i=0;i<M;i++) {
	    		update(offset+work[i][0],offset+work[i][1]);
	    	}
	    	for(int i=1;i<=maxDate;i++) {
	    		int currEmpCnt = query(offset+i);
	    		ANS += currEmpCnt>N? dp[currEmpCnt-N]:0;
	    	}
	    	//方法2:Indexed Tree ======end=========
	    	
	    	System.out.printf("#%d %d\n",testCase,ANS);
	    }
	    	
	}
	
	static void update(int start ,int end) {
		while(start<=end) {
			if(start%2==1) {
				idxTree[start]++;
			}
			if(end%2==0) {
				idxTree[end]++;
			}
			start=(start+1)>>1;
			end = (end-1)>>1;
		}
	}
	
	static int query(int index) {
		int res=0;
		while(index>0) {
			res += idxTree[index];
			index = index>>1;
		}
		return res;
	}

}

  

 

 

 

标签:10,日程,费用,int,Tree,Freelancer,static,Indexed,兼职
来源: https://www.cnblogs.com/smile_to_warm/p/15165019.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有