P4765 [CERC2014]The Imp 题解
首先,需要先得出一个结论,购买物品需要依照一个贪心的策略,购买的顺序需要按照
设
之后便是 DP 的转移,可以发现,从最后一件商品向前转移更为简单,为了下标的方便,这里将
设dp[i][j],表示从 dp[i][0]=max(dp[i-1][0],v[i]-c[i])。
进行转移,可得dp[i][j]=max(dp[i-1][j],min(v[i]-c[i],dp[i-1][j-1]-c[i])。
分析这个转移方程,dp[i-1][j]意味着并不选 min(v[i]-c[i],dp[i-1][j-1])表示小恶魔选取的更优秀的选项,即对于购买者更小的获利,其分别表示将 dp[n][k]。代码如下。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
int read(){int d=1,k=0;char c=getchar();
while(!(c>='0' and c<='9' or c=='-'))c=getchar();if(c=='-')d=-1,c=getchar();
while(c>='0' and c<='9')k=(k<<3)+(k<<1)+(c^48),c=getchar();return d*k;}
int dp[200000][10],n,k;
struct node{int value,cost;}a[1000000];
int cmp(node x,node y){return x.value>y.value;}
signed main(){
int T=read();
while(T--){
n=read(),k=read();
for(int i=1;i<=n;i++)a[i].value=read(),a[i].cost=read();
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)dp[i][0]=max(dp[i-1][0],a[i].value-a[i].cost);
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
dp[i][j]=max(dp[i-1][j],min(dp[i-1][j-1]-a[i].cost,a[i].value-a[i].cost));
}
}
printf("%lld\n",dp[n][k]);
}
return 0;
}