题目
Description
一家软件开发公司有两个项目,并且这两个项目都由相同数量的m个子项目组成,对于同一个项目,每个子项目都是相互独立且工作量相当的,并且一个项目必须在m个子项目全部完成后才算整个项目完成。
这家公司有n名程序员分配给这两个项目,每个子项目必须由一名程序员一次完成,多名程序员可以同时做同一个项目中的不同子项目。
求最小的时间T使得公司能在T时间内完成两个项目。
这家公司有n名程序员分配给这两个项目,每个子项目必须由一名程序员一次完成,多名程序员可以同时做同一个项目中的不同子项目。
求最小的时间T使得公司能在T时间内完成两个项目。
Input
第一行两个正整数n,m(1<=n<=100,1<=m<=100)。
接下来n行,每行包含两个整数,x和y。分别表示每个程序员完成第一个项目的子程序的时间,和完成第二个项目子程序的时间。每个子程序耗时也不超过100。
接下来n行,每行包含两个整数,x和y。分别表示每个程序员完成第一个项目的子程序的时间,和完成第二个项目子程序的时间。每个子程序耗时也不超过100。
Output
输出最小的时间T。
Sample Input
3 20
1 1
2 4
1 6
Sample Output
18
【样例解释】
第一个人做18个2项目,耗时18;第二个人做2个1项目,2个2项目耗时12;第三个人做18个1项目,耗时18。
Data Constraint
对于30%的数据,n<=30.
对于60%的数据,n<=60.
对于60%的数据,n<=60.
分析
- 首先二分答案是很容易想到的
- 所以我们就要知道如何用到DP
- 设f[i][j]为前i个人取了j个一项目,所能取二项目的最大值
-
f[i][j]=max(f[i][j],f[i-1][j-k]+(int)((mid-k*a[i])/b[i]));
- 大概意思就是枚举一个k,把做一的k的时间给二做
- 得到一个最大值
代码
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int a[1001],b[1001]; 5 int f[1001][1001]; 6 int n,m; 7 bool check(int mid) 8 { 9 for (int i=0;i<=n;i++) 10 for (int j=0;j<=m;j++) 11 f[i][j]=-1e9; 12 f[0][0]=0; 13 for (int i=1;i<=n;i++) 14 for (int j=0;j<=m;j++) 15 for (int k=0;k<=j;k++) 16 { 17 if(mid-k*a[i]<0) break; 18 f[i][j]=max(f[i][j],f[i-1][j-k]+(int)((mid-k*a[i])/b[i])); 19 } 20 21 if (f[n][m]>=m) return true; 22 else return false; 23 } 24 int main () 25 { 26 freopen("company.in","r",stdin); 27 freopen("company.out","w",stdout); 28 cin>>n>>m; 29 for (int i=1,x,y;i<=n;i++) 30 cin>>a[i]>>b[i]; 31 int l=1,r=10000,mid; 32 while (l<=r) 33 { 34 mid=l+r>>1; 35 if (check(mid)) r=mid-1; 36 else l=mid+1; 37 } 38 cout<<l; 39 }