解析:因为对于每个事件都有两个选择(要么发生、要么不发生),所以可以用动态规划来求解。因为对于每件事发生时的收益与当前的RP值有关,所以应该用RP值作为状态。用dp[i]表示RP为i时的最大收益,状态转移方程为:dp[i+a]=max(dp[i+a],dp[i]+c)(a为变化值、c为收益值)。不过RP可以为负,且分析题意可知RP∈[-10000,10000],所以状态值(数组下标)应为RP+10000.
下面是AC了的代码:
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int inf=0x3f3f3f3f;
int dp[20002];//分别表示加入或不加入当前数据
int main()
{
int T;//共有T组数据
cin>>T;
while(T--)
{
int N;
cin>>N;
memset(dp,-inf,sizeof(dp));//初始化dp的所有收益值为负无穷
dp[10000]=0;//初始收益值为0
int a,b,c;//变化值、门槛值、获益值
for(int i=1;i<=N;i++)
{
cin>>a>>b>>c;
//每一个事件都可以建立在原来的基础之上
if(a>0)
{
//a>0时要保证rp<=b
for(int j=10000+b;j>=0;j--)
dp[j+a]=max(dp[j+a],dp[j]+c);
}
else
{
for(int j=10000+b;j<20000;j++)
dp[j+a]=max(dp[j+a],dp[j]+c);
}
}
int Max=-inf;
for(int i=0;i<20010;i++)
if(dp[i]>Max)
Max=dp[i];
cout<<Max<<endl;
}
return 0;
}