题目描述
情人节这不刚过去没多久吗,我得给大家爆个料。这个事关于小飞飞的,小飞飞呢,要给她女票买礼物,但是呢有个比较尴尬的事情,小飞飞有些钱在某宝里,有些钱在某东里,众所周知,这俩可是死对头,想相互转钱是不可能的,于是小飞飞决定把这些钱用来给女票买礼物(可以花不完,因为这样的话小飞飞就可以给其她女生买礼物了)。 已知某宝中有c1元,某东里有c2元。大家都知道网上东西竞争很厉害,基本价格都是差不多的,但是质量就不好说了,所以呢,同一件物品在不同的地方买,花费同样的价格,但是得到的物品的好坏却不一样,我们就用一个好感度来衡量吧,那么花费同样的钱在某宝中的好感度为v1,在某东上的好感度为v2,为了使得小飞飞买的东西能够使他的女票尽可能的满意,当然她的女票不喜欢两件相同的东西,所以请大家帮帮他,否则,小飞飞就要受到残酷的惩罚了。啊~~~~~~~~~~~~~~~~~~(来自小飞飞崩溃的惨叫。。。)
输入
t组测试事例 每组有 n c1 c2 下面有n行 表示有n种商品,在某宝的余额为c1,某东的余额为c2,每行c v1 v2表示花费c元,在某宝的好感度为v1,某东的好感度为v2(n<=100, c1,c2<=500, t<=5)
输出
占一行 最大可以获得的最大好感度。
样例输入 样例输出
题目链接:http://acm.zznu.edu.cn/problem.php?id=1992
*************************************
题意:dp[i][j][k]表示第i件礼物,某宝还有j元钱,某东还有k元钱时可获得
的最大好感度。
分析:此状态由三种可能得到:
1.此物品不买(dp[i-1][j][k])
2.在某宝买(dp[i-1][j-v[i]][k]+w[i])
3.在某东买(dp[i-1][j][k-v[i]]+w[i])
取最大值即可。由01背包状态压缩可知,第一维是不需要的
需要注意的是数据有坑,可能某礼物需要的花费是0,这样如果比较和赋值同时进行可能会出现将某宝和某东的好感值都加上的情况.因此将三种状态全部遍历后再赋值.
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include<limits.h>
#include <cmath>
#include <cstdlib>
#include <stack>
#include <vector>
#include <queue>
#include <map> using namespace std; #define N 520
#define INF 0x3f3f3f3f
#define met(a, b) memset (a, b, sizeof (a))//// met (dist, -1); int dp[N][N]; int main()
{
int T,i,j,k; scanf("%d", &T); while(T--)
{
int n,c1,c2,c[N],v1[N],v2[N]; scanf("%d%d%d", &n,&c1,&c2); for(i=;i<n;i++)
scanf("%d%d%d", &c[i], &v1[i],&v2[i]); met(dp,);
int ans=; for(i=;i<n;i++)
for(j=c1;j>=;j--)
for(k=c2;k>=;k--)
{
int a=,b=;///一定要赋零
if(j>=c[i])
a=max(dp[j][k],dp[j-c[i]][k]+v1[i]);
if(k>=c[i])
b=max(dp[j][k],dp[j][k-c[i]]+v2[i]); dp[j][k]=max(dp[j][k],max(a,b));
ans=max(ans,dp[j][k]);
}
printf("%d\n", ans);
}
return ;
}