软件公司

题目描述
一家软件开发公司有两个项目,并且这两个项目都由相同数量的m个子项目组成,对于同一个项目,每个子项目都是相互独立且工作量相当的。由于时效性,两个项目必须同时被完成,如果其中一个完成的早了,那么这两个项目都会无效。

特别提醒:原文如此,题目实际意义是最晚的时间,并不是两个大项目必须要同时做完。比如项目1用16,项目2用18,则时间为18.

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

求公司完成两个项目的最少时间。

输入
第一行两个正整数n,m(1<=n<=100,1<=m<=100)。
接下来n行,每行包含两个整数,x和y。分别表示每个程序员完成第一个项目的子程序的时间,和完成第二个项目子程序的时间。每个子程序耗时也不超过100。

输出
包含一个整数,表示两个项目同时完成的时间。

样例输入
3 20
1 1
2 4
1 6

样例输出
18

提示
【样例解释】
第一个人做18个2项目,耗时18;第二个人做2个1项目,2个2项目耗时12;第三个人做18个1项目,耗时18。
【数据范围】
对于30%的数据,n<=30.
对于60%的数据,n<=60.

Solution

一开始被题意误导了很久,如果题面没歧义的话,我们其实很容易得到一个dp
f[i][x][y]i1x2y
这样是 nm4
其实我们可以发现,不必去求时间,我们可以枚举时间,来验证能否满足,那么二分就呼之欲出了
最后的优化就是不必把项目2当做第三维,我们可以调整dp数组含义如下
f[i][x]i1x2

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int a[105],b[105],f[105][105];
int erfen(int l,int r)
{
    if(l>r) return l;
    int mid=(l+r)/2;
    for(int i=0;i<=n;i++) 
    {
        for(int j=1;j<=m;j++) f[i][j]=-1e9;
        f[i][0]=0;
    }
    for(int i=1;i<=n;i++) 
    for(int j=0;j<=m;j++) 
    for(int k=0;k<=j;k++) 
    if(k*a[i]<=mid) f[i][j]=max(f[i][j],f[i-1][j-k]+(mid-k*a[i])/b[i]);
    if(f[n][m]>=m) return erfen(l,mid-1); else return erfen(mid+1,r);
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
    cout<<erfen(1,10000);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值