题目
输入
输出
样例输入
5
8 2
10 7
5 1
11 8
13 3
样例输出
27
数据范围
分析
很显然,这题是DP。
题目已经说的很清楚了,是01背包。
- 但是顺序是什么?
随便推一下就知道了,
就是代价的大小。
不过还有一些问题。
我们总共需要选择多少个?
选了这个之后后面还有多少个?
这些问题看似不是太容易解决。
如果我们倒着枚举,
枚举到的第一个就是最后一个放进去的,
这样即使我们不知道需要选多少个,
也可以知道这个后面有多少个。
- 好了,现在就开始DP
设 fi,j 表示前i个物品,我们选了j个
那么
fi,j=max(fi−1,j,fi−1,j−1+vi−wi∗(j−1))
code(c++)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
using namespace std;
struct note{int w,v;}a[5003];
int n,ans;
int f[5003][5003];
bool cmp(note x,note y){return x.w>y.w;}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].v,&a[i].w);
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
f[i][j]=max(f[i-1][j],f[i-1][j-1]-a[i].w*(j-1)+a[i].v);
for(int i=1;i<=n;i++)
ans=max(ans,f[n][i]);
printf("%d",ans);
}