洛谷 P1800 software_NOI导刊2010提高(06)

题目链接

题解

二分答案+dp

如果我们知道答案,贪心地想,让每个人做尽量多的模块一定不会比最优解差

\(f[i][j]\)表示前\(i\)个人第一个模块做了\(j\)块,第二个模块最多能做多少

然后我们枚举第\(i\)个人做多少块第一个模块,就可以算出第二个模块最多能做多少

取最大值即可

Code

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int f[N][N];
int a[N], b[N], n, m;

bool check(int x) {
	memset(f, 128, sizeof(f));
	f[0][0] = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= m; j++)
			for (int k = 0; k*a[i] <= x && k <= j; k++)
				f[i][j] = max(f[i][j], f[i-1][j-k]+(x-k*a[i])/b[i]);
	}
	return f[n][m] >= m;
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) scanf("%d%d", &a[i], &b[i]);
	int l = 0, r = 1000000;
	while (l <= r) {
		int mid = (l + r) >> 1;
		if (check(mid)) r = mid-1;
		else l = mid+1;
	}
	printf("%d\n", r+1);
	return 0;
}
posted @ 2018-11-08 19:24  zzy2005  阅读(106)  评论(0编辑  收藏  举报