从三道题品品 dp 优化的思路。
机缘巧合下最近连做了很多 dp 的题,出现了一些巧妙的优化,放一起感受感受。
观察转移式,循环 dp 数组的优化。
观察转移式,改维护前缀和作为 dp 的优化。
从最优子结构的角度考虑 dp 的优化。
Teleporting Takahashi 2 ABC-372 F Teleporting Takahashi 2 .
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 #include <bits/stdc++.h> #define int long long using namespace std;typedef pair<int , int > PII;constexpr int mod = 998244353 ;void solve () { int n, m, k; cin >> n >> m >> k; vector<PII>adj; while (m--){ int u, v; cin >> u >> v; u--, v--; adj.emplace_back (u, v); } int cur = 0 ; vector<int >dp (n, 1 ); for (int i = 1 ; i <= k; i++){ cur = (cur + 1 ) % n; vector<PII>adds; for (auto &[u, v] : adj){ int uu = (u + cur) % n; int vv = (v + cur - 1 + n) % n; adds.emplace_back (uu, dp[vv]); } for (auto &[u, val] : adds){ dp[u] = (dp[u] + val) % mod; } } cout << dp[cur] << '\n' ; } signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); solve (); return 0 ; }
Multiplicity Codeforces 1061C Multiplicity .
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 #include <bits/stdc++.h> using namespace std;constexpr int mod = 1e9 + 7 ;void solve () { int n; cin >> n; vector<int >a (n + 1 ); for (int i = 1 ; i <= n; i++) cin >> a[i]; vector<int >dp (n + 1 ); dp[0 ] = 1 ; for (int i = 1 ; i <= n; i++){ vector<int >l, r; for (int p = 1 ; p <= i && p * p <= a[i]; p++){ if (a[i] % p) continue ; l.emplace_back (p); if (p * p != a[i] && a[i] / p <= i) r.emplace_back (a[i] / p); } for (auto &u : r){ dp[u] += dp[u - 1 ]; dp[u] %= mod; } for (auto it = l.rbegin (); it != l.rend (); it++){ dp[*it] += dp[*it - 1 ]; dp[*it] %= mod; } } int res = 0 ; for (int i = 1 ; i <= n; i++) res = (res + dp[i]) % mod; cout << res << '\n' ; } signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); solve (); return 0 ; }
Game With Triangles: Season 2 Codeforces 2074G Game With Triangles: Season 2 .
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 #include <bits/stdc++.h> #define int long long using namespace std; void solve () { int n; cin >> n; vector<int >a (n + 1 ); for (int i = 1 ; i <= n; i++) cin >> a[i]; vector<vector<int >>dp (n + 2 , vector <int >(n + 2 )); for (int len = 3 ; len <= n; len++){ for (int l = 1 , r = len; r <= n; l++, r++){ for (int i = l + 1 ; i < r; i++){ dp[l][r] = max (dp[l][r], dp[l + 1 ][i - 1 ] + dp[i + 1 ][r - 1 ] + a[l] * a[i] * a[r]); } for (int i = l; i < r; i++){ dp[l][r] = max (dp[l][r], dp[l][i] + dp[i + 1 ][r]); } } } cout << dp[1 ][n] << '\n' ; } signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); int t; cin >> t; while (t--) solve (); return 0 ; }