n个物品,每个物品对应价格。
有种优惠,买物品A可以附赠价值小于A的k-1件商品
则,现有p数量钱,最多买几件物品?
原问题:优惠必须选k-1件赠品,多和少都不可以
思路:k间隔枚举,再在从小价值物品里面挑
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 200005
int num[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,p,k;
scanf("%d%d%d",&n,&p,&k);
for(int i=0;i<n;i++) scanf("%d",&num[i]);
sort(num,num+n);
int ans = 0;
for(int i=0;i<k;i++){
int sum = p;
int cnt = 0;
for(int j=i+k-1;j<n;j+=k){
if(sum>=num[j]){
sum -= num[j];
cnt += k;
}else{
break;
}
}
for(int j=0;j<i;j++){
if(sum >= num[j]){
sum -= num[j];
cnt++;
}else{
break;
}
}
ans = max(ans,cnt);
}
printf("%d\n",ans);
}
return 0;
}
进阶问题:优惠可以选0~k-1件赠品
思路:0~k-1开始k间隔枚举
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 200005
int num[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,p,k;
scanf("%d%d%d",&n,&p,&k);
for(int i=0;i<n;i++) scanf("%d",&num[i]);
sort(num,num+n);
int ans = 0;
int sum = p;
int cnt = 0;
for(int i=0;i<k;i++){
cnt = 0;
sum = p;
bool flag = true;
for(int j=i;j<n;j+=k){
if(sum >= num[j]){
sum-=num[j];
cnt = max(cnt,j+1);
}else{
ans = max(ans,cnt);
flag = false;
break;
}
}
if(flag) ans = max(ans,cnt);
}
printf("%d\n",ans);
}
return 0;
}