jzoj3515NOIP2013模拟11.6B组二分DP软件公司
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jzoj3515NOIP2013模拟11.6B组二分DP软件公司相关的知识,希望对你有一定的参考价值。
【NOIP2013模拟11.6B组】软件公司
题面
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.
解题思路
首先,其实很容易想到用二分求答案,但是怎样验证二分答案呢
我在考场上用的贪心,虽然我无法证明这个贪心的正确性,但是能拿70分
贪心是错的。。。。。
考虑DP,设
f
i
,
j
f_{i,j}
fi,j为前i个程序员,做j个一项目,最多可做
f
i
,
j
f_{i,j}
fi,j个二项目
然后就和背包差不多,设第i个程序员做k个一项目
已知时间、做第一个项目的单个时间、做第二个项目的单个时间及做多少个一项目,那么做多少个二项目就可以求出来了
做第一个项目的单个时间 * 做多少个一项目 + 做第二个项目的单个时间 * 做多少个二项目 = 时间
(时间 - 做第一个项目的单个时间 * 做多少个一项目) / 做第二个项目的单个时间 = 做多少个二项目
f
i
,
j
=
m
a
x
(
f
i
,
j
,
f
i
−
1
,
j
−
k
+
(
m
i
d
−
a
[
i
]
.
x
∗
k
)
/
a
[
i
]
.
y
)
f_{i,j}=max(f_{i,j},f_{i-1,j-k}+(mid-a[i].x * k)/a[i].y)
fi,j=max(fi,j,fi−1,j−k+(mid−a[i].x∗k)/a[i].y)
Code
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct DT{
int x, y;
}a[2000];
int n, m, l, r, mid, ans, f[1100][1100];
int check(int x) {
memset(f, -0x7f, sizeof(f));
for(int j = 0; j * a[1].x <= x; j++) //预处理出一,因为前面都没有做,f为-0x7f
f[1][j] = (x - j * a[1].x) / a[1].y;
for(int i = 2; i <= n; i++)
for(int j = 0; j <= m; j++)
for(int k = 0; k * a[i].x <= x; k++)
if(f[i - 1][j - k] >= 0) //前面能做到j-k个一项目
f[i][j] = max(f[i][j], f[i - 1][j - k] + (x - k * a[i].x) / a[i].y);
if(f[n][m] >= m) return 1;
return 0;
}
int main() {
// freopen("company.in", "r", stdin);
// freopen("company.out", "w", stdout);
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%d %d", &a[i].x, &a[i].y);
r = max(r, a[i].x + a[i].y);
}
r = r * m;
while(l <= r) {
mid = (l + r) / 2;
if(check(mid)) r = mid - 1, ans = mid;
else l = mid + 1;
}
printf("%d", ans);
}
以上是关于jzoj3515NOIP2013模拟11.6B组二分DP软件公司的主要内容,如果未能解决你的问题,请参考以下文章
jzoj3508NOIP2013模拟11.5B组DAY 1 (7.12)HASH好元素(good)
[jzoj]3506.NOIP2013模拟11.4A组善良的精灵(fairy)(深度优先生成树)
jzoj3505NOIP2013模拟11.4A组组合逆元积木
[jzoj]3456.NOIP2013模拟联考3恭介的法则(rule)