Files
python/TangDou/AcWing/BeiBao/【总结】脑图形式(二维)总结.md
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

3.1 KiB
Raw Blame History

背包问题(二维求法)

求方案数

  • 体积至多j
    • 初始:f[0][i]=1,$0<=i<=m$,其余为0
    • $01$背包
    •   for (int j = 0; j <= m; j++) {
          f[i][j] = f[i - 1][j];
          if (j >= v) f[i][j] += f[i - 1][j - v];
        }
      
    • 完全背包
    •   for (int j = 0; j <= m; j++) {
        f[i][j] = f[i - 1][j];
            if (j >= v) f[i][j] += f[i][j - v];
        }
      
  • 体积恰好j
    • 初始:f[i][0]=1,$0<=i<=n$,其余为0
    • $01$背包
    • for (int j = 0; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] += f[i - 1][j - v];
          }
      
    • 完全背包
    • for (int j = 0; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] += f[i][j - v];
          }
      
  • 体积至少j
    • 初始:f[0][0]=1,其余为0
    • $01$背包
    • for (int j = 0; j <= m; j++)
         f[i][j] = f[i - 1][j] + f[i - 1][max(0, j - v)];
      
    • 完全背包代码
    • 有无穷多组方案数,不这么问

求最大/小值

  • 体积至多j
    • 初始:f[i,j]=0,0 <= i <= n, 0 <= j <= m
    • $01$背包
    • for (int j = 0; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] = max(f[i][j], f[i - 1][j - v] + w);
          }
      
    • 完全背包
    • for (int j = 1; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] = max(f[i][j], f[i][j - v] + w);
          }
      
  • 体积恰好j
    • 求最小值
      • 初始化f[0][0]=0,其它是INF
      • 01 背包
      • for (int j = 0; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] = min(f[i][j], f[i - 1][j - v] + w);
          }
        
      • 完全背包
      • for (int j = 0; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] = min(f[i][j], f[i][j - v] + w);
          }
        
    • 求最大值
      • 初始化f[0][0]=0, 其余是−INF
      • 01背包 
      • for (int j = 0; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] = max(f[i][j], f[i - 1][j - v] + w);
          }
        
      • 完全背包
      •  for (int j = 0; j <= m; j++) {
              f[i][j] = f[i - 1][j];
              if (j >= v) f[i][j] = max(f[i][j], f[i][j - v] + w);
          }
        
  • 体积至少j
    • 求最小值
      • 初始化f[0][0]=0, 其余是INF
      • 01背包 
      •   for (int j = 0; j <= m; j++)
              f[i][j] = min(f[i - 1][j], f[i - 1][max(0, j - v)] + w);
        
      • 完全背包
      •  for (int j = 0; j <= m; j++)
              f[i][j] = min(f[i - 1][j], f[i][max(0, j - v)] + w); 
        
    • 求最大值
      • 没有求最大值的