【简】题解 AWSL090429 【价值】

先考虑当要选的物品一定时 显然有个贪心 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;
}
原文地址:https://www.cnblogs.com/1436177712qqcom/p/10806086.html