P2647 最大收益 (動態規劃)
阿新 • • 發佈:2018-09-27
include www 題目 明顯 play cin 方程 () pro
題目鏈接
Solution
乍一看發現正著 DP,有明顯的後效性,所以就反過來做.
但是同時發現很顯然減去多的放後面明顯更優,所以按 \(R\) 從大排序.
然後 \(f[i][j]\) 代表前 \(i\) 個選了 \(j\) 個的最大價值.
轉移方程:
\[f[i][j]=max(f[i-1][j],f[i-1][j-1]+a[i].w-a[i].r*(j-1));\]
Code
#include<bits/stdc++.h> #define N 3002 #define ll long long using namespace std; struct sj{ll w,r;}a[N]; ll f[N][N],n,ans; bool cmp(sj s,sj j){return s.r>j.r;} int main() { cin>>n; for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i].w,&a[i].r); sort(a+1,a+n+1,cmp); f[0][0]=0; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) f[i][j]=max(f[i-1][j],f[i-1][j-1]+a[i].w-a[i].r*(j-1)); for(int i=1;i<=n;i++) ans=max(ans,f[n][i]); cout<<ans<<endl; }
P2647 最大收益 (動態規劃)