nn.Linear nn.Conv2d nn.BatchNorm2d
阿新 • • 發佈:2020-08-29
01揹包:指的是每種物品只能選0次或1次的揹包問題。
在01揹包的基礎上說一下閆氏dp分析法:
狀態計算使用的集合劃分方法:
#include<iostream> using namespace std; const int N = 1010; int n, m; int f[N][N]; int w[N], v[N]; int main(){ cin >> n >> m; for(int i = 1; i <= n; i ++) cin >> v[i] >> w[i]; //f[0][1 ~ m] = 0 for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++){ //對照圖2看一下 f[i][j] = f[i - 1][j]; // 左側集合必存在 if(j - v[i] >= 0) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); // 此處判斷是因為如果右側集合為空就不要再求max了 } cout << f[n][m] << endl; return 0; }
將空間從二維優化為1維,用程式碼等價變形的方法。
(不要從程式碼推思路,要根據思路寫程式碼。--yxc)
#include<iostream> using namespace std; const int N = 1010; int n, m; int f[N]; int w[N], v[N]; int main(){ cin >> n >> m; for(int i = 1; i <= n; i ++) cin >> v[i] >> w[i]; for(int i = 1; i <= n; i ++) for(int j = m; j >= v[i]; j --)//注意此處需要倒著來的原因:如果不倒著來==> f[j - v[i]]先被計算,就不是第i - 1層的f[j - v[i]]了,而是第i層的f[j - v[i]] f[j] = max(f[j], f[j - v[i]] + w[i]); cout << f[m] << endl; return 0; }
綜上dp的分析方法就是:確定狀態是什麼元素的集合,狀態需要用幾維表示,狀態存了集合的什麼屬性,一個狀態表示的集合應當怎麼劃分(從而計算出當前狀態的屬性值),題目的答案是哪一個狀態。