题意:
给出N(15W)个物品,每个物品有c[i](cost)、v[i](value)两个值,
对方能释放k(<=9)次魔法,使得一个物品的v[i]变为0,求在双方均使用最优策略的情况下,我方能得到一件有价值的物品,使得最大。
也可以不买任何东西。
思路:
对于对方来说,必然是释放所有魔法,这样使得我方损失最大。
对于我方来说,假设购买的物品为a1、a2.....an,那么价值是递增的(因为总花费一样,价值大的放后面显然更优)。
将物品按value值排序,然后dp既可。
用dp[i][j]表示前i种物品,释放了j次魔法最大值。
转移方程:dp[i][j]=max(dp[i+1][j],min(a[i].v-a[i].c,dp[i+1][j-1]-a[i].c))。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int MAX=150005;
LL dp[MAX][15];
struct Node{
LL v,c;
}a[MAX];
bool cmp(Node a,Node b){
return a.v<b.v;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&a[i].v,&a[i].c);
}
sort(a+1,a+1+n,cmp);
memset(dp,-INF,sizeof(dp));
for(int j=0;j<=k;j++){
dp[n+1][j]=0;
}
for(int i=n;i>=1;i--){
for(int j=0;j<=k;j++){
if(j) dp[i][j]=max(dp[i+1][j],min(a[i].v-a[i].c,dp[i+1][j-1]-a[i].c));
else dp[i][j]=max(dp[i+1][j],a[i].v-a[i].c);
}
}
printf("%lld\n",dp[1][k]);
}
return 0;
}