洛谷 P1800 software_NOI導刊2010提高(06)
阿新 • • 發佈:2018-11-08
題目連結
題解
二分答案+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; }