题目大意:将一组物品分成两组,每个物品都可以不出现在任何一组。希望两组的重量差异不超过M,最大化总重量。

https://ac.nowcoder.com/acm/problem/19158

基本就是一个背包问题的变体,对于前i个物品,差异为gap时的最大总重量进行dp即可。
转移为(i, gap) -> (i + 1, gap)和(i, gap) -> (i + 1, gap + wt[i + 1])和(i, gap) -> (i + 1, abs(gap - wt[i + 1]))。注意,gap的中间值是可以超过M的,需要给一个比较大的界,比如w1+...+wn。

#define MAXN 105
#define MAXW 20000
#define INF 20000
int N, M;
int wt[MAXN];
int dp[MAXN][MAXW];
int doit() {
  REP(i, N) {
    int w = wt[i];
    if (i == 0) {
      REP(j, MAXW) {
        dp[i][j] = -INF;
      }
      dp[i][0] = 0;
      dp[i][w] = w;
      continue;
    }
    REP(j, MAXW) {
      dp[i][j] = dp[i - 1][j];
    }
    REP(j, MAXW) {
      VI trans = {j + w, abs(j - w)};
      for (int t : trans) {
        if (0 <= t && t < MAXW) {
          dp[i][t] = max(dp[i][t], dp[i - 1][j] + w);
        }
      }
    }
  }
  int ans = 0;
  REP(j, M + 1) {
    ans = max(ans, dp[N - 1][j]);
  }
  return ans;
}
int main(int argc, char* argv[]) {
  read(N);read(M);
  read(wt, N);
  printint(doit());
  return 0;
}