Pagini recente » Cod sursa (job #486339) | Cod sursa (job #2120340) | Cod sursa (job #2361696) | Cod sursa (job #1726376) | Cod sursa (job #2710450)
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("lapte.in");
ofstream fout("lapte.out");
const int NMAX = 128;
class person {
public:
int a, b;
} v[NMAX], sol[NMAX][NMAX];
int N, L, dp[NMAX][NMAX];
bool check(const int &x) {
for(int i = 0; i <= N; ++i)
for(int j = 0; j <= L; ++j)
dp[i][j] = -INF;
dp[0][0] = 0;
// dp[i][j] - cantitatea maxima de lapte B bauta de primele i persoane in timpul maxim indicat
// cu conditia ca acestea sa fi baut pana acum j litri de lapte A
for(int i = 1; i <= N; ++i) // ma aflu la persoana i
for(int j = 0; j <= L; ++j) // j litri de lapte A bauti pana acum
for(int k = 0; k <= j && v[i].a * k <= x; ++k) { // k din cei j litri ii bea persoana i(trebuie sa se si incadreze in timp)
int rem_time = x - (v[i].a * k); // atata timp ii mai ramane ca sa mai bea lapte B
int add = rem_time / v[i].b; // atata lapte B poate bea
if(dp[i][j] < dp[i - 1][j - k] + add) { // vad daca am obtinut o solutie mai buna
dp[i][j] = dp[i - 1][j - k] + add;
sol[i][j] = person{k, add};
}
}
return dp[N][L] >= L; // vad daca am reusit sa beau L litri din ambele tipuri de lapte
}
void solve(const int &A, const int &B) {
if(A == 1) {
fout << sol[A][B].a << ' ' << sol[A][B].b << '\n';
return;
}
solve(A - 1, B - sol[A][B].a);
fout << sol[A][B].a << ' ' << sol[A][B].b << '\n';
}
int main() {
fin >> N >> L;
for(int i = 1; i <= N; ++i)
fin >> v[i].a >> v[i].b;
int st = 1, dr = 1e4, ans = 1e4 + 1;
while(st <= dr) {
int mid = (st + dr) >> 1;
if(check(mid)) {
ans = mid;
dr = mid - 1;
}
else
st = mid + 1;
}
fout << ans << '\n';
check(ans);
solve(N, L);
}