
如果说难的话,难就难在对阶段的划分。
这又是一道对值域空间进行分段的题目。
因为rp有正有负,所以将整个数组向右平移10000个单位长度
l和r分别是rp可能的最小值
因为b是“门槛”,所以如果
发生好事(即c>0)循环就从b到r
发生坏事(即c<0)循环从l到b
然后从左到右找出最大值即可
//#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int INF = -;
const int maxn = + ;
int rp[maxn]; int main(void)
{
#ifdef LOCAL
freopen("1574in.txt", "r", stdin);
#endif int N;
scanf("%d", &N);
while(N--)
{
int n;
scanf("%d", &n);
for(int i = ; i < maxn; ++i)
rp[i] = INF;
int l, r;
l = r = ;
rp[l] = ; while(n--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
b += ; if(a < )
{
for(int i = b; i <= r; ++i)
rp[i+a] = max(rp[i+a], rp[i]+c);
l += a;
}
else
{
for(int i = b; i >= l; --i)
rp[i+a] = max(rp[i+a], rp[i]+c);
r += a;
}
}
int ans = ;
for(int i = l; i <= r; ++i)
ans = max(ans, rp[i]);
printf("%d\n", ans);
}
return ;
}
代码君