題目: UVa - 11566 - Let’s Yum Cha!
題目說明
Unfortunate狗的ACM園地: 11566 - Let’s Yum Cha!
解題思路
先算出總共可用的金額,之後 DP 求解即可。
定義 dp[j][k]
表示最多可以選擇 j
盤點心,共有 k
元預算。
dp[j][k] = max(dp[j - 1][k - price[i]], max(dp[j - 1][k], dp[j][k]))
最後的 dp[j][k]
也要取是因為縮減了一維,原本應為 dp[i][j][k]
,縮減的那一維意義為只可選擇前 i
種點心,因此 dp[j][k]
也要放進來比較,意義為若多一種點心可選擇,但滿意度減少,則不如不多該選擇。
由於 DP 縮減了一維,所以計算時要從後面往前算。
參考解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include <bits/stdc++.h>
using namespace std;
static auto __ = [] { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); return 0; }();
int N, X, T, K; int V; int favor[201]; int price[201]; int dp[23][1001];
void read() { memset(dp, 0, sizeof(dp));
++N; V = int((X * N) / 1.1 + 1e-9); V -= T * N;
for (int i = 0, tmp; i < K; ++i) { int sum = 0; cin >> tmp; price[i << 1] = price[(i << 1) + 1] = tmp; for (int j = 0; j < N; ++j) cin >> tmp, sum += tmp; favor[i << 1] = favor[(i << 1) + 1] = sum; } }
void solve() { for (int i = 0; i < K * 2; ++i) { for (int j = N * 2; j > 0; --j) for (int k = price[i]; k <= V; ++k) { dp[j][k] = max(dp[j - 1][k - price[i]] + favor[i], max(dp[j - 1][k], dp[j][k])); } }
int mx = INT_MIN; for (int i = 0; i <= 2 * N; ++i) mx = max(dp[i][V], mx); cout << setprecision(2) << fixed << (double)mx / N << '\n'; }
int main() { while (cin >> N >> X >> T >> K && (N || X || T || K)) { read(); solve(); } }
|
參考資料
[UVA] 11566 - Let's Yum Cha! | 水泥城式