2020.01.18【NOIP提高组】模拟B 组——总结——选择困难症

Polo面临在有限预算下做出午餐选择的挑战,需要在多个菜品中找到第K便宜的组合价格。通过二分搜索结合DFS算法,在给定的菜品价格列表中找到满足条件的最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

又到吃饭时间,Polo面对饭堂里琳(fei)琅(chang)满(keng)目(die)的各种食品,又陷入了痛苦的抉择中:该是吃手(jiao)打肉饼好呢,还是吃豆(cai)角(chong)肉片好呢?嗯……又不是天秤座怎么会酱紫呢?
具体来说,一顿饭由M个不同的部分组成(荤菜,素菜,汤,甜品,饮料等等),Polo要在每个部分中选一种作为今天的午饭。俗话说的好,永远没有免费的午餐,每种选择都需要有一定的花费。长者常常教导我们,便宜没好货,最便宜的选择估计比较坑爹,可囊中羞涩的Polo还要把钱省下来给某人买生日礼物,这该怎么办呢?
于是一个折中方案出来了:第K便宜的组合要花多少钱?这就要靠你了。

Input

第一行两个数M,K,含义如上所述。
接下来M行,先是一个整数Ai,表示第i个部分有多少种选择。接下来用空格分开的Ai个整数表示每种选择的价格。

Output

一行一个整数表示答案。
【样例解释】
最便宜的选择是第一部分选择1块钱的,第二部分选择2块的。但由于第二部分里2块钱有两种不同的选择,所以第二便宜的总花费仍然是3块。

Sample Input

2 2
2 1 3
2 2 2

Sample Output

3

Data Constraint

在这里插入图片描述

赛时

显然a[i]很大,但是m也小的可怜。想过dp,但是最后打了个二分+dfs+剪枝,当场ac

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
int m,k;
int c[17][500007],a[17];
ll l,r,mid,g,ans;
void dfs(int x,ll sum){
    if(x==m+1){
		g++;
        return;
    }
    if(g>=k) return;
    for(int i=1;i<=a[x];i++){
        if(c[x][i]>sum) return;
        dfs(x+1,sum-c[x][i]);
    }
}
int main(){
    scanf("%d%d",&m,&k);
    for(int i=1;i<=m;i++){
        scanf("%d",&a[i]);
        for(int j=1;j<=a[i];j++) 
			scanf("%d",&c[i][j]);
        sort(c[i]+1,c[i]+a[i]+1);
        l+=c[i][1],r+=c[i][a[i]];
    }
    while(l<=r){
        g=0;
        mid=(l+r)/2;
        dfs(1,mid);
        if(g>=k) r=mid-1,ans=mid;
        else l=mid+1;
    }
    printf("%lld",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值