题解:P4928 [MtOI2018] 衣服?身外之物!

· · 题解

考虑设计状态:

这里我们实现扩散型的转移: $$dp_{i, j} \rightarrow dp_{i + 1, k} + z_{i + 1} \times y_v$$ 其中 $k$ 表示当第 $i + 1$ 天穿第 $v$ 件衣服时 $n$ 件衣服需要洗的天数构成的集合,要保证第 $v$ 件衣服是可以穿的。 注意:每一天过后如果当一件衣服要洗,那么这件衣服需要洗的天数会 $-1$。 代码如下: ```cpp #include<bits/stdc++.h> using namespace std; const int N = 2e3 + 5; const int M = 8; const long long inf = 1e10; const long long INF = 5e15; int n, m, a[M], x[N], y[N], z[N], power[N]; long long dp[N][M * M * M * M]; int main(){ cin >> n >> m; power[0] = 1; for(int i = 1; i <= n; i++){ power[i] = power[i - 1] * 7; } for(int i = 0; i < n; i++){ cin >> x[i]; } for(int i = 0; i < n; i++){ cin >> y[i]; } for(int i = 1; i <= m; i++){ cin >> z[i]; } for(int i = 0; i <= m; i++){ for(int j = 0; j < power[n]; j++) dp[i][j] = -INF; } dp[0][0] = 0; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++) a[j] = 0; for(int j = 0; j < power[n]; j++){ if(j > 0) a[0]++; for(int i = 0; i < n && a[i] >= 7; a[i] -= 7, a[++i]++); int num = 0; for(int i = 0; i < n; i++) num += max(0, a[i] - 1) * power[i]; for(int k = n - 1; k >= 0; k--){ if(!a[k]){ int v = num + y[k] * power[k]; dp[i + 1][v] = max(dp[i + 1][v], dp[i][j] + x[k] * z[i + 1]); } } } } long long ans = -INF; for(int i = 0; i < power[n]; i++){ ans = max(ans, dp[m][i]); } if(ans < -inf){ cout << "gcd loves her clothes!"; return 0; } cout << ans; return 0; } ```