这道题其实就是双塔问题。

每个物品有三种选择:放天平左边,放天平右边,不要这个物品。 代表前i个元素天平左右相差(左-右)的时候最大的重量是多少。如果放天平左边,就应该由转移来,如果放在天平右边就由转移来,不选则由转移来。
注意:左-右可能为负数,所以要对数轴进行一个平移。

#include <algorithm>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <list>
#include <map>
#include <iomanip>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define int long long
#define I inline
#define ri register int
#define For(i , x , y) for(ri i = x ; i <= y ; ++ i)
#define Next(i , x) for(ri i = head[x] ; i ; i = e[i].nxt)
#define pb(x) push_back(x)
#define lowbit(x) x & -x
I int read() {
    int s = 0 , w = 1; char ch = getchar();
    while(ch < 48 || ch > 57) {if(ch == '-') w = -1; ch = getchar();}
    while(ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48) , ch = getchar();
    return s * w;
}

const int N = 105;
int a[105];
int dp[110][110005];
signed main() {
    int n = read() , m  =read();
    int cnt = 0;
    for(int i = 1 ;i <= n ; ++i ){
        a[i] = read();
        cnt += a[i];
    }
    memset(dp , -0x3f , sizeof(dp));
    dp[0][0] = 0;
    for(int i = 1 ; i <= n ;++i){
        for(int j = 0 ; j <= cnt ; ++j){
            dp[i][j] = dp[i-1][j];
            int tmp = max(dp[i-1][j+a[i]],dp[i-1][abs(j-a[i])]);
            dp[i][j] = max(dp[i][j],tmp+a[i]);
        }
    }
    int ans = 0;
    for(int i = 0 ; i <= m ;++i){
        ans = max(ans,dp[n][i]);
    }
    cout << ans << endl;

    return 0;
}