/** * author: zjs * created: 23.06.2026 21:48:31 **/ #include #include // does not include cassert since GCC 16. using namespace std; #ifdef LOCAL #include "debug.h" #else #define debug(...) 42 #endif int main() { ios::sync_with_stdio(0); cin.tie(0); int N, W; cin >> N >> W; //所选物品的任意子集的总重量在 -10000 到 W + 10000 // dp[i][j]:从前 i 个物品中选一些,所选物品的总重量不超过 j,所选物品的总价值的最大值。 int offset = 10000; const int mod = 998244353; int len = W + 20000 + 1; const int INF = INT_MIN / 2; vector dp(len, INF); vector cnt(len); for (int i = offset; i < len; i++) { dp[i] = 0; cnt[i] = 1; } for (int j = 0; j < N; j++) { int v, w; cin >> v >> w; vector new_dp(len, INF); vector new_cnt(len); for (int i = 0; i < len; i++) { if (0 <= i - w && i - w < len && dp[i - w] != INF) { if (dp[i] < v + dp[i - w]) { new_dp[i] = v + dp[i - w]; new_cnt[i] = cnt[i - w]; } else if (dp[i] > v + dp[i - w]) { new_dp[i] = dp[i]; new_cnt[i] = cnt[i]; } else { new_dp[i] = dp[i]; new_cnt[i] = (cnt[i] + cnt[i - w]) % mod; } } else { new_dp[i] = dp[i]; new_cnt[i] = cnt[i]; } } dp = new_dp; cnt = new_cnt; } cout << dp[W + offset] << ' ' << cnt[W + offset] << '\n'; }