【解题报告】洛谷P4138 挂饰

题目链接

https://www.luogu.com.cn/problem/P4138

思路

f[i][j]f[i][j] 表示挂了前 ii 个挂饰,还剩下 jj 个挂的位置,可以得到的最大的喜悦值是多少

这就是一个背包
f[i][j]=max(f[i1][j],f[i1][max(jc[i].a,0)+1]+c[i].b) f[i][j]=max(f[i-1][j],f[i-1][max(j-c[i].a,0)+1]+c[i].b)
其中如果加上挂钩之后小于零了之后,那就只挂在手机上了,所以是还剩下一个的那种情况,然后观察状态转移方程可以使用滚动数组优化一下就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#define int long long
using namespace std;
const int maxn=2005;
struct node{
int a,b;
}c[maxn];
int n,ans=-1e9;
int f[5][maxn];
bool cmp(node x,node y)
{
return x.a>y.a;
}
signed main()
{
memset(f,-0x3f3f3f,sizeof(f));
cin>>n;
for(int i=1;i<=n;i++)
cin>>c[i].a>>c[i].b;
sort(c+1,c+1+n,cmp);
f[0][1]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=n;j++)
f[i&1][j]=max(f[(i-1)&1][j],f[(i-1)&1][max(j-c[i].a,1ll*0)+1]+c[i].b);
}
for(int i=0;i<=n;i++)
ans=max(ans,f[n&1][i]);
cout<<ans<<'\n';
return 0;
}