二分+动态规划 POJ 1973 Software Company

Software Company

Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 1112   Accepted: 482

Description

A software developing company has been assigned two programming projects. As both projects are within the same contract, both must be handed in at the same time. It does not help if one is finished earlier.

This company has n employees to do the jobs. To manage the two projects more easily, each is divided into m independent subprojects. Only one employee can work on a single subproject at one time, but it is possible for two employees to work on different subprojects of the same project simultaneously.

Our goal is to finish the projects as soon as possible.

Input

The first line of the input file contains a single integer t (1 <= t <= 11), the number of test cases, followed by the input data for each test case. The first line of each test case contains two integers n (1 <= n <= 100), and m (1 <= m <= 100). The input for this test case will be followed by n lines. Each line contains two integers which specify how much time in seconds it will take for the specified employee to complete one subproject of each project. So if the line contains x and y, it means that it takes the employee x seconds to complete a subproject from the first project, and y seconds to complete a subproject from the second project.

Output

There should be one line per test case containing the minimum amount of time in seconds after which both projects can be completed.

Sample Input

1
3 20
1 1
2 4
1 6

Sample Output

18
 1 /*既然动态规划方程中要转移的量太多,那么我们就把时间作为二分的对象,对时间进行二分,假设一个最短时间(每个人都不能超过的时间),进行DP,f[i][j]表示是前i个人做j个A项目所能做的最多的B项目的数目,
 2 方程:d[i][j] = max { d[i][j] ,  d[i][j - k] +  (time - A[i] * k) / B[i] }
 3 枚举第i个人做k个A项目,剩下的时间用来做B项目,只要检查d[i][m]》=m就是能够到这个时间。
 4 当然我们也可以用滚动数组压缩空间。*/
 5 #define N 101
 6 #include<iostream>
 7 using namespace std;
 8 #include<cstdio>
 9 #include<cstring>
10 struct QU{
11     int n,m,A[N],B[N],f[N];
12     void init(int x,int y)
13     {
14         n=x;m=y;
15         memset(A,0,sizeof(A));
16         memset(B,0,sizeof(B));
17         memset(f,0,sizeof(f));
18     }
19     void add(int a,int b,int i)
20     {
21         A[i]=a;B[i]=b;
22     }
23     bool check(int V)
24     {
25         memset(f,-1,sizeof(f));
26         for(int i=0;i<=m;++i)
27         {/*初始化第一个人的做i个A项目的情况*/
28             if(i*A[1]>V) break;
29             f[i]=max(f[i],(V-i*A[1])/B[1]);
30         }
31         if(f[m]>=m) return true;
32         for(int i=2;i<=n;++i)
33         {
34             for(int j=m;j>=0;--j)
35             {/*枚举前i-1人做了多少个A*/
36                 for(int k=0;k<=j;++k)
37                 {/*枚举第i个人做了k个A项目*/
38                     if(V<k*A[i]) break;
39                     if(f[j-k]!=-1)
40                     f[j]=max(f[j],f[j-k]+(V-k*A[i])/B[i]);
41                 /*注意前-1个人可能做不到j-k个项目,这时候如果转移,那就是前i-1个人总共花了-1时间,显然不合题意*/
42                                 }
43             }
44             if(f[m]>=m) return true;
45         }
46         return false;
47     }
48 }Q;
49 int main()
50 {
51     int tes;
52     scanf("%d",&tes);
53     int n,m;
54     while(tes--)
55     {
56         scanf("%d%d",&n,&m);
57         Q.init(n,m);
58         int a,b;
59         int maxx=-1;
60         for(int i=1;i<=n;++i)
61         {
62             scanf("%d%d",&a,&b);
63             Q.add(a,b,i);
64             maxx=max(maxx,max(a,b));
65         }
66         int l=0,r=maxx*m*2;
67         int mid;
68         while(l<=r)
69         {
70             mid=(l+r)>>1;
71             if(Q.check(mid))
72             r=mid-1;
73             else l=mid+1;
74         }
75         printf("%d\n",l);
76
77     }
78     return 0;
79 }
时间: 2024-08-14 01:00:29

二分+动态规划 POJ 1973 Software Company的相关文章

任务调度分配题两道 POJ 1973 POJ 1180(斜率优化复习)

POJ 1973 这道题以前做过的.今儿重做一次.由于每个程序员要么做A,要么做B,可以联想到0/1背包(谢谢N巨).这样,可以设状态 dp[i][j]为i个程序员做j个A项目同时,最多可做多少个B项目.枚举最后一个程序员做多少个A项目进行转移(0/1). dp[i][j]=max{dp[i-1][k]+(time-(j-k)*a[i])/b[i]}.于是,二分时间time进行判定即可. #include <iostream> #include <cstdio> #include

搜索+剪枝 POJ 1416 Shredding Company

POJ 1416 Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5231   Accepted: 2964 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would

poj 1416 -- Shredding Company

Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4114   Accepted: 2324 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would just shre

POJ 3216 Repairing Company【Floyd + 最小路径覆盖】

大意: 有n个任务,每个任务有三个属性:所在街区,最晚开始时间,执行需要时间 告诉你一个矩阵代表街区间到达时间 告诉你每个任务的三个属性 问最少需要多少人去完成所有任务 分析: floyd处理处任意两个街区的到达时间 拆点   左边集合为n个任务    右边集合跟左边相同 i任务能够到达j任务就从左集合引一条边到右集合 求最小路径覆盖 最小路径覆盖 = n - 最大匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include

[二分+容斥原理] poj 2773 Happy 2006

题目链接: http://poj.org/problem?id=2773 Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9131   Accepted: 3073 Description Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1.

POJ 3216 Repairing Company(最小路径覆盖)

POJ 3216 Repairing Company 题目链接 题意:有m项任务,每项任务的起始时间,持续时间,和它所在的block已知,且往返每对相邻block之间的时间也知道,问最少需要多少个工人才能完成任务,即x最少是多少 思路:先floyd求出每两个block之间的最小距离,然后就是最小路径覆盖问题,一个任务之后能赶到另一个任务就建边 代码: #include <cstdio> #include <cstring> #include <algorithm> #i

poj 1416 Shredding Company (DFS)

Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4595   Accepted: 2633 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would just shre

POJ 1416 Shredding Company【dfs入门】

题目传送门:http://poj.org/problem?id=1416 Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6860   Accepted: 3710 Description You have just been put in charge of developing a new shredder for the Shredding Company Although a "

POJ 3216 Repairing Company

题目链接 http://poj.org/problem?id=3216 题目解释 题意:莉莉是一家维修公司,服务这个城市的 Q 块.有一天,公司收到M修复任务,其中第 i 个发生在Pi块,对任何修理工的到来的最后到来期限的Ti,就是它的起始时间,并需要一个修理工  Di  时间完成.修理工完成当前单个任务,必须在移动(移动到下一个块需要消耗时间)到下一个完成下一个任务.有地图在手,莉莉想知道最少的修理工,才能够完成金今天所有的任务. 输入:首先输入两个数 Q, M, 代表有 Q 个块, M个任务