1. 程式人生 > 實用技巧 >nn.Linear nn.Conv2d nn.BatchNorm2d

nn.Linear nn.Conv2d nn.BatchNorm2d

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的分析方法就是:確定狀態是什麼元素的集合,狀態需要用幾維表示,狀態存了集合的什麼屬性,一個狀態表示的集合應當怎麼劃分(從而計算出當前狀態的屬性值),題目的答案是哪一個狀態。