描述
度度熊拥有一个自己的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
提示
度度熊拥有一个自己的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;
}
1003

被折叠的 条评论
为什么被折叠?



