紫薯第9章动态规划,从入门到入土, dp 它tnl(背包代码模板部分)

背包问题

01背包

每件物品最多只使用一次。

for(int i=1; i<=n; i ++ ){
    
    
    int v, w;
    cin>>v>>w;
    for(int j=m; j>=v; j--){
    
    
        dp[j] = max(dp[j],dp[j-v]+w);
    }
}

完全背包

每件物品可以使用无限次。

for(int i=1; i<=n; i++){
    
    
    int v, w;
    cin>>v>>w;
    for(int j=0; j<=m; j++){
    
     
        if(j>=v)dp[j] = max(dp[j],dp[j-v]+w);
    }
}

多重背包

每件物品最多使用 s [ i ] s[i] s[i] 次。
朴素写法

for(int i = 1; i <= n; i ++ ){
    
    
   int v, w, s;
    cin>>v>>w>>s;
    for(int j=m; j >= 1; j--){
    
    
        for(int k = 1; k <= s; k ++ ){
    
    
            if(k*v<=j)dp[j] = max(dp[j],dp[j-k*v]+k*w);
        }
    }
}

n m l o g s nmlogs nmlogs二进制优化,利用倍增的思想

cin>>n>>m;
for(int i = 1; i <= n; i ++ ){
    
    
    int a, b, c;
    cin>>a>>b>>c;
    int k = 1;
    while(k<=c){
    
    
        v[cnt] = k*a;
        w[cnt] = k*b;
        cnt++;
        c -= k;
        k <<= 1;
    }
    if(c > 0){
    
    
        v[cnt] = c*a;
        w[cnt] = c*b;
        cnt++;
    }
}
for(int i = 0; i < cnt; i ++ ){
    
    
    for(int j=m; j>=v[i]; j--){
    
    
        dp[j] = max(dp[j], dp[j-v[i]]+w[i]);
    }
}
cout<<dp[m]<<endl;

分组背包

每组中最多只可以选择一个物品。

cin>>n>>m;
for(int i = 0; i < n; i ++ ){
    
    
    cin>>s[i];
    for(int j = 0; j < s[i]; j ++ ){
    
    
        cin>>v[i][j]>>w[i][j];
    }
}
for(int i = 0; i < n; i ++ ){
    
    
    for(int j = m; j >= 0; j -- ){
    
    
        for(int k = 0; k < s[i]; k++){
    
    
            if(j>=v[i][k])dp[j] = max(dp[j], dp[j-v[i][k]] + w[i][k]);
        }
    }
   
} 

猜你喜欢

转载自blog.csdn.net/qq_45377553/article/details/112059666