洛谷 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;
}

猜你喜欢

转载自www.cnblogs.com/zzy2005/p/9931364.html