P2647 最大收益

ccsc推荐的dp题 

其实我一开始并没有想出来qwq

定义dp[i][j]表示前i个物品买j个得到的最大收益

然后就不会了

翻了翻题解

发现应该倒着推

那么dp[i][j]=max( dp[i-1][j],dp[i-1][j-1]+w[i]-(j-1)*r[i] );

其实就是从 前i-1个物品取j个 和 前i-1个物品取j-1个并加上第j个可以得到的价值 中取最大值

由此可以证明 

我们应将r[i]从大到小排序 这样才能使价值最大

//P2647 最大收益
#include<bits/stdc++.h>
using namespace std;
struct get{
    int w,r;
}a[3005];
int dp[3005][3005];
bool cmp(get a,get b){
    return a.r>b.r;
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i].w,&a[i].r);
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+a[i].w-a[i].r*(j-1));
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        ans=max(ans,dp[n][i]);
    }
    cout<<ans;
    return 0;
}
原文地址:https://www.cnblogs.com/duojiaming/p/11734510.html