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; }