题目链接
【题目描述】
一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每个软件划分成m个模块,由公司里的技术人员分工完成,每个技术人员完成同一软件的不同模块的所用的天数是相同的,并且是已知的,但完成不同软件的一个模块的时间是不同的,每个技术人员在同一时刻只能做一个模块,一个模块只能由一个人独立完成而不能由多人协同完成。一个技术人员在整个开发期内完成一个模块以后可以接着做任一软件的任一模块。写一个程序,求出公司最早能在什么时候交付软件。
【输入】
输入文件第一行包含两个由空格隔开的整数n和m。
接下来的n行每行包含两个用空格隔开的整数d1和d2,d1表示该技术人员完成第一个软件中的一个模块所需的天数,d2表示该技术人员完成第二个软件中的一个模块所需的天数。
【输出】
输出文件仅有一行包含一个整数d,表示公司最早能于d天后交付软件。
【输入样例】
3 20
1 1
2 4
1 6
【输出样例】
18
【数据规模】
对于100%的数据,1≤n≤100,1≤m≤100,1≤d1,d2≤100。
【样例说明】
最快的方案是第一个技术人员完成第二个软件的18个模块,用时18天,第三个技术人员完成第一个软件的18个模块,用时18天,其余的模块由第二个技术人员完成,用时12天,做完所有的模块需要18天。如果第一个技术人员完成第二个软件的17个模块,第三个技术人员完成第一个软件的17个模块,其余的模块由第二个技术人员完成,需要用时18天,做完所有模块仍然需要18天,所以少于18天不可能做完所有模块。
思路
2分答案,然后用dp判断(dp过程见代码,类似背包DP)
参考代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define pass puts("pass")
#define LL long long
#define N 105
#define M 105
using namespace std;
int n,m,ans;
int a[N],b[N];
bool dp[M+M][M+M];
bool work(int p) {
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1; i<=n; i++)
for(int x=m; x>=0; x--)
for(int y=m; y>=0; y--)
if(dp[x][y])
for(int k=0; k*a[i]<=p; k++) {
int z=(p-k*a[i])/b[i];
dp[min(x+k,m)][min(m,y+z)]=1;
if(dp[m][m])
return 1;
}
return 0;
}
int main() {
cin>>n>>m;
for(int i=1; i<=n; i++)
scanf("%d%d",&a[i],&b[i]);
int l=0,r=M;
while(l<=r) {
int mid=(l+r)/2;
if(work(mid)) {
ans=mid;
r=mid-1;
} else {
l=mid+1;
}
}
cout<<ans<<endl;
return 0;
}