先考虑当要选的物品一定时 显然有个贪心 wi越小的要越先选
所以先按wi从小到大拍序
因为发现正着递推要记录的状态很多 并且wi的贡献与后面选了几个物品有关
考虑正难则反 倒着递推 提前计算wi的贡献就可以了
#include<bits/stdc++.h> using namespace std; #define ll long long #define C getchar()-48 inline ll read() { ll s=0,r=1; char c=C; for(;c<0||c>9;c=C) if(c==-3) r=-1; for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c; return s*r; } const int N=5e3+10; int n,mx; struct xin{ int v,w; }a[N]; int v[N],w[N]; int dp[N][N]; inline bool pd(xin a,xin b) { return a.w<b.w; } int main() { freopen("value.in","r",stdin); freopen("value.out","w",stdout); n=read(); for(int i=1;i<=n;i++) a[i].v=read(),a[i].w=read(); sort(a+1,a+1+n,pd); for(int i=1;i<=n;i++) v[i]=a[i].v,w[i]=a[i].w; for(int i=n;i>=1;i--) for(int j=1;j<=n+1-i;j++) dp[i][j]=max(dp[i+1][j],dp[i+1][j-1]+v[i]-(j-1)*w[i]); for(int i=1;i<=n;i++) mx=max(mx,dp[1][i]); cout<<mx; return 0; }