star3

描述
度度熊拥有一个自己的Baidu空间,度度熊时不时会给空间朋友赠送礼物,以增加度度熊与朋友之间的友谊值。度度熊在偶然的机会下得到了两种超级礼物,于是决定给每位朋友赠送一件超级礼物。不同类型的朋友在收到不同的礼物所能达到的开心值是不一样的。开心值衡量标准是这样的:每种超级礼物都拥有两个属性(A, B),每个朋友也有两种属性(X, Y),如果该朋友收到这个超级礼物,则这个朋友得到的开心值为A*X + B*Y。


由于拥有超级礼物的个数限制,度度熊很好奇如何分配这些超级礼物,才能使好友的开心值总和最大呢?


输入
第一行n表示度度熊的好友个数。
接下来n行每行两个整数表示度度熊好朋友的两种属性值Xi, Yi。
接下来2行,每行三个整数ki, Ai, Bi,表示度度熊拥有第i种超级礼物的个数以及两个属性值。
1 <= n <= 1000, 0 <= Xi, Yi, Ai, Bi <= 1000, 0 <= ki <= n, 保证k1+k2 >= n
输出
输出一行一个值表示好友开心值总和的最大值
样例输入
4
3 6
7 4
1 5
2 4
3 3 4
3 4 3
样例输出
118
提示

送给第一种礼物的人有1,3,4,送给第二种礼物的人有2




也可以看做背包问题的扩展,设对于朋友i,获得礼物a的快乐是ai,获得礼物b的快乐是bi,对于朋友i要判断是放入a还是b

f[k1,k2] = max{ f[k1-1][k2]+ai,f[k1][k2]+bi }



#include <iostream>
#include <stdio.h>
#include <sstream>
#include <cstring>
#include <vector>

using namespace std;

class term
{
public:
	int x;
	int y;

	int a;
	int b;
	int k;//1 or 2
};

int numa;
int numb;
int aa[2];
int bb[2];
vector<term> fd(1000);
int f[1001][1001];
//vector<vector<vector<int> > >
int main()
{

	int n;
	scanf("%d",&n);
	for (int i=0;i<n;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		fd[i].x = x;
		fd[i].y = y;

	}

	scanf("%d%d%d",&numa,&aa[0],&aa[1]);
	scanf("%d%d%d",&numb,&bb[0],&bb[1]);
	

	for (int i=0;i<n;++i)
	{
		fd[i].a = fd[i].x * aa[0] + fd[i].y *aa[1];
		fd[i].b = fd[i].x *bb[0] + fd[i].y *bb[1];
	}

	memset(f,0,sizeof(f));
	for (int i=0;i<n;++i)
	{
		for (int ai = numa;ai>=1;--ai)
		{
			for (int bi = numb;bi>=1;--bi)
			{
				int seleta = f[ai-1][bi] +fd[i].a;
				int seletb = f[ai][bi-1] +fd[i].b;
				f[ai][bi] = seleta>seletb?seleta :seletb;
			}
		}
	}

	cout<<f[numa][numb]<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值