[kungbin] 專題12 基礎DP
阿新 • • 發佈:2021-09-08
01
04[和最大上升子序]
題目:
給定n個數字,選出一組遞增子序列,使得和最大
分析:
把最長上升子序的遞推公式改成求和
程式碼:
#include <bits/stdc++.h> using namespace std; int n; int a[1010]; int dp[1010]; void work() { // cin >> n; for (int i = 1; i <= n; i ++ ) cin >> a[i], dp[i] = a[i]; int ans = 0; for (int i = 1; i <= n; i ++ ) { for (int j = 1; j < i; j ++ ) if (a[i] > a[j]) dp[i] = max(dp[i], dp[j] + a[i]); ans = max(ans, dp[i]); } cout << ans << endl; } int main() { while (cin >> n, n) { work(); } return 0; }
05 [完全揹包求體積恰好為m的最小值]
題目:
如標籤一樣,完全揹包求提及恰好為m的最小值
分析:
注意初始化,dp[0] = 0, 其他的都是無窮大,這樣答案只能從0轉移來,不會從其他的地方轉移而來
程式碼:
#include <bits/stdc++.h> using namespace std; int n, m, mm, mmm; int dp[10005]; void work() { //使填裝揹包的體積恰好為m,且價值最低 cin >> mm >> mmm; m = mmm - mm; cin >> n; memset(dp, 0x3f, sizeof dp); dp[0] = 0; int w, v; for (int i = 1; i <= n; i ++ ) { cin >> w >> v; for (int j = v; j <= m; j ++ ) dp[j] = min(dp[j], dp[j - v] + w); } if (dp[m] != 0x3f3f3f3f) printf("The minimum amount of money in the piggy-bank is %d.\n", dp[m]); else puts("This is impossible."); } int main() { int t; cin >> t; while (t -- ) work(); return 0; }