Problem
Description
Input
Output
Sample Input
5
8 2
10 7
5 1
11 8
13 3
Sample Output
27
Data Constraint
Solution
我们可以发现,求总价值其实就是求选的物品本来的价值再减去代价。那么如果我们决定要选哪些物品,就要先选W[i]较小的。我们知道选择倒数第i个物品的代价是
wi∗(i−1)
。
我们按照W[i]从大到小排序,所以我们选物品的时候倒着选一定最优。
设
F[i][j]
表示从前i个物品中选择后j个得到的最大价值。依题意得:
f[i][j]=max(f[i−1][j],f[i−1][j−1]+v[i]−w[i]∗(j−1))
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#define N 5010
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
int v[N],w[N],i,j,k,l,n,m,t,s,f[N][N],_2[11],ans;
void qsort(int l,int r)
{
int i=l,j=r,mid=w[(l+r)/2];
while (i<j)
{
while (w[i]>mid) i++;
while (w[j]<mid) j--;
if (i<=j)
{
swap(w[i],w[j]);
swap(v[i],v[j]);
i++;j--;
}
}
if (l<j) qsort(l,j);
if (i<r) qsort(i,r);
}
int main()
{
_2[1]=1;
fo(i,2,9) _2[i]=_2[i-1]*2;
scanf("%d",&n);
fo(i,1,n) scanf("%d%d",&v[i],&w[i]);
qsort(1,n);
fo(i,1,n)
fo(j,1,i)
{
f[i][j]=max(f[i-1][j],f[i-1][j-1]+v[i]-w[i]*(j-1));
ans=max(ans,f[i][j]);
}
printf("%d",ans);
}
——2016.8.17