版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/89763722
title
【问题描述】
【输入】
【输出】
【输入输出样例1】
value.in
5
8 2
10 7
5 1
11 8
13 3
value.out
27
【数据范围】
analysis
这道题一眼看过去,以为排个序做个背包就好,但发现
会超时,就尴尬了。。看一下数据,很明显是要
,
。
那要怎么
呢。
我们先按
降序的排序,然后贪心的想,我们一定是从后往前取的。设
表示前
个物品,从后往前取了
个的最大价值。 那么第
个物品的真正价值就是
,即减去对在它后面取的物品(排序在它前面的物品)的影响。
总式为
。
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e3+10;
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
struct Orz{int v,w;}a[maxn];
inline bool cmp(Orz x,Orz y)
{
return x.w>y.w;
}
ll f[maxn][maxn],ans;
int main()
{
freopen("value.in","r",stdin);
freopen("value.out","w",stdout);
int n;read(n);
for (int i=1; i<=n; ++i) read(a[i].v),read(a[i].w);
sort(a+1,a+n+1,cmp);
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j)
f[i][j]=max(f[i-1][j],f[i-1][j-1]+a[i].v-(j-1)*a[i].w);
for (int i=1; i<=n; ++i) ans=max(ans,f[n][i]);
printf("%lld\n",ans);
return 0;
}