题意:
有n个商品,每个商品价值为 ai 现在有一个活动优惠,买一个物品可以选择k - 1个价值小于等于该它的物品免费获得(要么一个也不选,要么一定要选k - 1个),求p个硬币一共能买多少物品。在该题中k <= n。
思路:
因为要尽量多,所以送的能拿一定拿,而且要拿贵的。对价格排个序
定义dp[i]表示买前i个用的最少的钱
dp方程式:i>=k时:dp[i]=min(dp[i-1)+a[i],dp[i-k]+a[i]) i<k时 dp[i]=dp[i-1)+a[i];
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
const ll mod = 1e9+7;
int a[maxn];
int dp[maxn];
int main() {
int T;
scanf("%d",&T);
while(T--)
{
int n,p,k;
scanf("%d%d%d",&n,&p,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
int ans=0;
for(int i=1;i<=n;i++)
{
dp[i]=dp[i-1]+a[i];
if(i>=k)
dp[i]=min(dp[i-k]+a[i],dp[i]);
if(dp[i]<=p)
ans=max(ans,i);
}
printf("%d\n",ans);
}
return 0;
}
/**
*/