题目
Bessie has N (1≤N≤2000) friends. However, not all friends are created equal! Friend i has a popularity score of Pi (1≤Pi≤2000), and Bessie wants to maximize the sum of the popularity scores of the friends accompanying her. Friend ii is only willing to accompany Bessie if she gives them Ci (1≤Ci≤2000) moonies. They will also offer her a discount of 1 mooney if she gives them Xi(1≤Xi≤2000) ice cream cones. Bessie can get as many whole-number discounts as she wants from a friend, as long as the discounts don't cause the friend to give her mooney.
Bessie has A moonies and B ice cream cones at her disposal (0≤A,B≤2000). Help her determine the maximum sum of the popularity scores she can achieve if she spends her mooney and ice cream cones optimally!
输入
Line 1 contains three numbers N, A, and B, representing the number of friends, the amount of mooney, and the number of ice cream cones Bessie has respectively.
Each of the next N lines contains three numbers, Pi, Ci, and Xi, representing popularity (Pi), mooney needed to bribe friend ii to accompany Bessie (Ci), and ice cream cones needed to receive a discount of 1 mooney from friend i (Xi).
输出
Output the maximum sum of the popularity scores of the friends accompanying Bessie, assuming she spends her moonie and ice cream cones optimally.
样例输入
3 10 8
5 5 4
6 7 3
10 6 3
样例输出
15
题目大意
小B有n个朋友,每个朋友有一个受欢迎度pi。小B想邀请部分朋友和他去看电影,且想要最大化这些朋友的受欢迎程度之和。对于朋友i,只有当小B给他ci元钱,他才会答应去。如果小B BB给他xi
个冰激凌,他还可以给小B 一元的折扣。小B可以从朋友那里得到任意整数数量的折扣,只要不是这些朋友倒贴他。小B 有a 元钱和b个冰激凌,求他在采用最佳策略的情况下,可以达到的最大的受欢迎程度之和。
1<=n<=2000,0<=a,b,<=2000,1<=ci,xi,pi<=2000
题解
首先会想到f[i][j],i表示钱,j表示冰淇淋,这样dp要n^3显然不行;
那么就会想到钱和冰淇淋分开dp,要满足达到最大很显然冰淇淋要用在xi小的人身上,所以我们对数据按照xi的大小升序排序,让[1,k-1]的人用冰淇淋,[k+1,n]的人用钱,k用冰淇淋和钱,这样就只需要n^2了。用f[i][j]标记前i个人用j个冰淇淋的最大值;用 dp[i][j]标记第n个人到第i个人用j个钱的最大价值。
AC代码
#include <bits/stdc++.h>
using namespace std;
class tt
{
public:
long long p, c, x;
};
tt a[2007];
long long f[2007][2007], dp[2007][2007];
int cmp(tt x, tt y)
{
return x.x < y.x;
}
void solve()
{
memset(f, 0, sizeof f);
memset(dp, 0, sizeof dp);
int n, m, l;
cin >> n >> m >> l;
for (int i = 1; i <= n; i++)
{
cin >> a[i].p >> a[i].c >> a[i].x;
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i++)
{
long long mm = a[i].c * a[i].x;
for (int j = 0; j < mm && j <= l; j++)
{
f[i][j] = f[i - 1][j];
}
for (int j = mm; j <= l; j++)
{
f[i][j] = max(f[i - 1][j], f[i - 1][j - mm] + a[i].p);
}
}
for (int i = n; i > 0; i--)
{
for (int j = 0; j < a[i].c && j <= m; j++)
{
dp[i][j] = dp[i + 1][j];
}
for (int j = a[i].c; j <= m; j++)
{
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - a[i].c] + a[i].p);
}
}
long long maxx = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= a[i].c && j <= m; j++)
{
if ((a[i].c - j) * a[i].x > l) //
{
maxx = max(maxx, f[i - 1][l] + dp[i + 1][m]);
}
else
{
maxx = max(maxx, f[i - 1][l - (a[i].c - j) * a[i].x] + dp[i + 1][m - j] + a[i].p);
}
}
}
cout << maxx << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}