题目:http://acm.hdu.edu.cn/showproblem.php?pid=5410
题解: 题目大意:别想偷懒,赶紧过去自己翻译。
我的思路:因为第一次买的时候获得价值和后来不一样,但也只有第一次和后来的花费不一样,所以我们可以先用01背包把第一次跑一遍,然后再用完全背包跑一遍。我最开始的错误思路是用一次完全背包跑一遍,然后设个标志,如果一个物品被放进去了,就标记一下,下次再放这个物品的时候就不不带a*x+b的那个b了,但是这样行不通,大家可以思考一下为什么行不通,我个人感觉这个和深搜里面的回溯差不多因为动规我不会回溯。
下面附上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[2500];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int M, N;
scanf("%d%d", &M, &N);
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= N; i++)
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
for(int j = M; j >= x; j--) // 01背包
dp[j] = max(dp[j], dp[j-x]+y+z);
for(int j = x; j <= M; j++) // 完全背包
dp[j] = max(dp[j], dp[j-x]+y);
}
printf("%d\n", dp[M]);
}
}