题目点这!!!!
/*01背包还可以这样用,
长见识了
对于w[i] > 0 和 w[i] <= 0
两种情况分开讨论
滚动数组来理解
注意w[i] <= 0 的数组边界问题
还有一点是坐标偏移
以正的代表负的,这样就可以限定很多条件
这些条件就可以应用到题目中去了
选与不选这不就是01背包问题吗*/
#include <iostream>
#include <cstring>
using namespace std;
const int M = 2e5 + 10;
const int node = 1e5;
int n;
int dp[M];
void bag01(int v, int w)
{
if (w > 0)
{
for (int i = M; i >= w; --i)
{
dp[i] = max(dp[i], dp[i - w] + v);
}
}
else
{
for (int i = 0; i < M + w; ++i)
{
dp[i] = max(dp[i], dp[i - w] + v);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
memset(dp, -0x3f3f3f3f, sizeof dp);
dp[node] = 0;
for (int i = 1; i <= n; ++i)
{
int w, v;
cin >> w >> v;
bag01(v, w);
}
int ans = 0;
for (int i = node; i <= M; ++i)
{
if (dp[i] > 0)
ans = max(ans, dp[i] + i - node);
}
if (ans >= 0)
cout << ans << endl;
else
cout << "0" << endl;
return 0;
}