JZOJ 3515. 软件公司

题目

Description

一家软件开发公司有两个项目,并且这两个项目都由相同数量的m个子项目组成,对于同一个项目,每个子项目都是相互独立且工作量相当的,并且一个项目必须在m个子项目全部完成后才算整个项目完成。

这家公司有n名程序员分配给这两个项目,每个子项目必须由一名程序员一次完成,多名程序员可以同时做同一个项目中的不同子项目。

求最小的时间T使得公司能在T时间内完成两个项目。
 

Input

第一行两个正整数n,m(1<=n<=100,1<=m<=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.

 

分析

 

  • 首先二分答案是很容易想到的
  • 所以我们就要知道如何用到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 }

 

posted @ 2019-08-21 20:41  Melted_czj  阅读(136)  评论(0编辑  收藏  举报
body { background-color:whitesmoke; } // 修改背景颜色为半透明 #home,#sideBarMain>div,#blog-sidecolumn>div>div,.catListView{ background-color:rgba(255,255,255,0); } // 修改其他边框的颜色