思路:
dp+滚动数组。
类似01背包。
实现:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 6 const int INF = 0x3f3f3f3f; 7 const int t = 100000; 8 int a[105], b[105], dp[2][200005], n, p, q; 9 int solve(int n) 10 { 11 for (int i = 0; i < 2; i++) 12 { 13 for (int j = -t; j <= t; j++) 14 { 15 dp[i][j + t] = -INF; 16 } 17 } 18 for (int i = 0; i < 2; i++) 19 dp[i][a[i] + t] = b[i]; 20 for (int i = 1; i < n; i++) 21 { 22 for (int j = -t; j <= t; j++) 23 { 24 dp[i & 1][j + t] = max(dp[(i - 1) & 1][j + t], dp[i & 1][j + t]); 25 if (j + t - a[i] < 0 || j + t - a[i] > 200000) 26 continue; 27 dp[i & 1][j + t] = max(dp[i & 1][j + t], dp[(i - 1) & 1][j + t - a[i]] + b[i]); 28 } 29 } 30 int ans = -INF; 31 for (int j = 0; j <= t; j++) 32 { 33 ans = max(ans, dp[(n - 1) & 1][j + t] >= 0 ? j + dp[(n - 1) & 1][j + t] : -INF); 34 } 35 return ans; 36 } 37 38 int main() 39 { 40 cin >> n; 41 int cnt = 0; 42 for (int i = 0; i < n; i++) 43 { 44 cin >> p >> q; 45 if (p < 0 && q < 0) 46 continue; 47 a[cnt] = p; 48 b[cnt++] = q; 49 } 50 int ans = solve(cnt); 51 if (ans <= -INF) 52 cout << "0" << endl; 53 else 54 cout << ans << endl; 55 return 0; 56 }