Mamy do przygotowania
Obliczyć minimalną ilość pieniędzy, którą musimy zapłacić za czas, w którym kucharze nie będą pracować.
W podzadaniu 3 mamy
Tak więc wystarczy, żeby
Na koniec odpowiedzią jest
const int N = 310; int n,m,k,a[N],b[N]; int dp[N*N],suma,sumb; int main() { scanf("%d%d%d",&n,&m,&k); REP(i,n) scanf("%d",&a[i]); REP(i,m) scanf("%d",&b[i]); REP(i,n) suma += a[i]; REP(i,m) sumb += b[i]; dp[0] = 1; REP(i,m) { for (int j = sumb-b[i]; j >= 0; --j) { dp[j + b[i]] |= dp[j]; } } int ans = -1; for (int j = sumb; j >= suma; --j) { if (dp[j]) ans = j - suma; } if (ans == -1) printf("Impossible"); else printf("%d\n", ans); }
W ogólnym przypadku musimy jeszcze zagwarantować, żeby każda potrawa była
przygotowywana przez co najmniej
Dla każdego kucharza i każdej potrawy oznaczmy pierwszą godzinę, przez którą ten
kucharz pracuje nad tą potrawą jako „specjalną”.
Zatem musimy przydzielić dokładnie
Zatem dla podzbioru kucharzy
Okazuje się, że jest to warunek wystarczający (bo konstruując przypisanie potraw kucharzom z podzbioru wystarczy na początku przydzielić godziny specjalne, a potem resztę jakkolwiek).
Tak więc chcemy znaleźć taki podzbiór
Poniższa modyfikacja również działa w złożoności czasowej
REP(i,n) if (a[i] < k) { printf("Impossible\n"); return 0; } REP(i,sumb+1) dp[i] = -infty; dp[0] = 0; REP(i,m) { for (int j = sumb-b[i]; j >= 0; --j) { dp[j + b[i]] = max(dp[j + b[i]], dp[j] + min(b[i], n)); } } int ans = -1; for (int j = sumb; j >= suma; --j) { if (dp[j] >= n*k) ans = j - suma; }