Codeforces 417D Cunning Gena【排序+状压dp】

本文探讨了在有限资源条件下,如何通过合理的策略安排,使得比赛中的问题得以最优化解决。重点介绍了状态转移方程的应用,以及如何结合选手能力和所需资源进行最优匹配。

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

D. Cunning Gena
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

A boy named Gena really wants to get to the "Russian Code Cup" finals, or at least get a t-shirt. But the offered problems are too complex, so he made an arrangement with his n friends that they will solve the problems for him.

The participants are offered m problems on the contest. For each friend, Gena knows what problems he can solve. But Gena's friends won't agree to help Gena for nothing: the i-th friend asks Gena xi rubles for his help in solving all the problems he can. Also, the friend agreed to write a code for Gena only if Gena's computer is connected to at least ki monitors, each monitor costs b rubles.

Gena is careful with money, so he wants to spend as little money as possible to solve all the problems. Help Gena, tell him how to spend the smallest possible amount of money. Initially, there's no monitors connected to Gena's computer.

Input

The first line contains three integers nm and b (1 ≤ n ≤ 1001 ≤ m ≤ 201 ≤ b ≤ 109) — the number of Gena's friends, the number of problems and the cost of a single monitor.

The following 2n lines describe the friends. Lines number 2i and (2i + 1) contain the information about the i-th friend. The 2i-th line contains three integers xiki and mi (1 ≤ xi ≤ 1091 ≤ ki ≤ 1091 ≤ mi ≤ m) — the desired amount of money, monitors and the number of problems the friend can solve. The (2i + 1)-th line contains mi distinct positive integers — the numbers of problems that the i-th friend can solve. The problems are numbered from 1 to m.

Output

Print the minimum amount of money Gena needs to spend to solve all the problems. Or print -1, if this cannot be achieved.

Examples
input
2 2 1
100 1 1
2
100 2 1
1
output
202
input
3 2 5
100 1 1
1
100 1 1
2
200 1 2
1 2
output
205
input
1 2 1
1 1 1
1
output
-1

题目大意:

一共有M个问题,有N个小伙伴可以帮你解决问题,其中一个监视器的金额为b。

对应接下来N组输入,对应每组输入两行,对应表示第i个小伙伴的信息,其中第一行包含三个元素,第一个元素表示雇佣这个小伙伴帮忙解决问题的花费,第二个表示这个小伙伴帮忙解决问题所需要的监视器的个数,第三个元素表示这个小伙伴能够解决的问题数。

(假如第一个小伙伴需要1个监视器,第二个小伙伴需要两个监视器,那么一共建立起来两个监视器就能同时满足两个条件)

接下来一行,表示能够解决问题的编号。

对应解决M个问题,求一个最小花费方案。


思路:


1、首先不考虑这个监视器的问题:

①对应观察到M只有20,那么我们可以对应设定dp【i】表示雇佣小伙伴解决了状态i时候的这些问题的最小花费。其中i=5.对应二进制表示:101,那么我们就能够表示5这个状态能够解决第一个和第三个问题,但是现在没有解决第二个问题。

②那么不难想到状态转移方程:dp【q】=min(dp【q】,dp【j】+a【i】.val)(其中对应第i个人能够解决状态q比状态j多出来的问题)

③对应解决上式状态转移方程,我们设定tmp【i】表示第i个人能够解决问题的状态,(例如tmp【1】=5,表示第1个人能够解决第一个和第三个问题,但是解决不了第二个问题。)那么我们此时第一层for枚举人,从0到n,然后第二层for枚举状态j,然后判断一下状态j下,有没有第i个人能够解决的问题并且状态j没有解决完的问题,对应判断:if(tmp【i】&j==tmp【i】)那么说明状态j已经解决了所有第i个人能够解决的问题,否则相反,并且我们同时设定q=j|a【i】;那么,dp【q】=min(dp【q】,dp【j】+a【i】.val);

此时状态转移过程最终结果dp【(1<<m)-1】就是解决了所有问题m所需要的最小雇佣花费。


2、那么此时考虑这个监视器问题;

①我们可以二分监视器个数,但是时间复杂度略高,可能会T

②我们其实直接将N个人按照需要监视器的个数从小到大排序即可,那么对应在将每个人都状态转移完毕之后,我们维护一次最小值:

ans=min(ans,dp【(1<<m)-1】+a【i】.yi*b),其中a【i】.yi表示当前这个人需要的监控器个数、这样保证前i个人进行了状态转移之后,当前这第i个人就是需要监控器个数最多的人,那么对应在雇佣的最小花费的基础上,维护一个最小总花费即可。


3、注意数组大小,注意数据范围,注意dp数组初始化大小,需要long long int的数据的地方不要忘记即可。


Ac代码:


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll __int64
#define inf 2000000000000000000
struct node
{
    int xi;
    ll yi,pos;
}a[1515];
int n,m;
ll b;
int tmp[151515];
ll dp[(1<<20)+15];
int cmp(node a,node b)
{
    return a.yi<b.yi;
}
int main()
{
    while(~scanf("%d%d%I64d",&n,&m,&b))
    {
        for(int i=0;i<(1<<m);i++)dp[i]=inf;
        memset(tmp,0,sizeof(tmp));
        for(int i=0;i<n;i++)
        {
            int k;
            scanf("%d%I64d%d",&a[i].xi,&a[i].yi,&k);
            while(k--)
            {
                int x;
                scanf("%d",&x);
                x--;
                tmp[i]+=(1<<x);
            }
            a[i].pos=i;
        }
        sort(a,a+n,cmp);
        dp[0]=0;
        ll ans=inf;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<(1<<m);j++)
            {
                int pos=a[i].pos;
                if((j&tmp[pos])!=tmp[pos])
                {
                    int q=j|tmp[pos];
                    dp[q]=min(dp[q],dp[j]+a[i].xi);
                }
            }
            if(dp[(1<<m)-1]!=inf)
            {
                ans=min(dp[(1<<m)-1]+a[i].yi*b,ans);
            }
        }
        if(ans==inf)printf("-1\n");
        else
        printf("%I64d\n",ans);
    }
}











在探索智慧旅游的新纪元中,一个集科技、创新与服务于一体的整体解决方案正悄然改变着我们的旅行方式。智慧旅游,作为智慧城市的重要分支,旨在通过新一代信息技术,如云计算、大数据、物联网等,为游客、旅游企业及政府部门提供无缝对接、高效互动的旅游体验与管理模式。这一方案不仅重新定义了旅游行业的服务标准,更开启了旅游业数字化转型的新篇章。 智慧旅游的核心在于“以人为本”,它不仅仅关注技术的革新,更注重游客体验的提升。从游前的行程规划、信息查询,到游中的智能导航、个性化导览,再到游后的心情分享、服务评价,智慧旅游通过构建“一云多屏”的服务平台,让游客在旅游的全过程中都能享受到便捷、个性化的服务。例如,游客可以通过手机APP轻松定制专属行程,利用智能语音导览深入了解景点背后的故事,甚至通过三维GIS地图实现虚拟漫游,提前感受目的地的魅力。这些创新服务不仅增强了游客的参与感和满意度,也让旅游变得更加智能化、趣味化。 此外,智慧旅游还为旅游企业和政府部门带来了前所未有的管理变革。通过大数据分析,旅游企业能够精准把握市场动态,实现旅游产品的精准营销和个性化推荐,从而提升市场竞争力。而政府部门则能利用智慧旅游平台实现对旅游资源的科学规划和精细管理,提高监管效率和质量。例如,通过实时监控和数据分析,政府可以迅速应对旅游高峰期的客流力,有效预防景区超载,保障游客安全。同时,智慧旅游还促进了跨行业、跨部门的数据共享与协同合作,为旅游业的可持续发展奠定了坚实基础。总之,智慧旅游以其独特的魅力和无限潜力,正引领着旅游业迈向一个更加智慧、便捷、高效的新时代。
内容概要:本文详细介绍了大模型的发展现与未来趋势,尤其聚焦于DeepSeek这一创新应用。文章首先回顾了人工智能的定义、分类及其发展历程,指出从摩尔定律到知识密度提升的转变,强调了大模型知识密度的重要性。随后,文章深入探讨了DeepSeek的发展路径及其核心价值,包括其推理模型、思维链技术的应用及局限性。此外,文章展示了DeepSeek在多个行业的应用场景,如智能客服、医疗、金融等,并分析了DeepSeek如何赋能个人发展,具体体现在公文写作、文档处理、知识搜索、论文写作等方面。最后,文章展望了大模型的发展趋势,如通用大模型与垂域大模型的协同发展,以及本地部署小模型成为主流应用渠道的趋势。 适合人群:对人工智能和大模型技术感兴趣的从业者、研究人员及希望利用DeepSeek提升工作效率的个人用户。 使用场景及目标:①了解大模型技术的最新进展和发展趋势;②掌握DeepSeek在不同领域的具体应用场景和操作方法;③学习如何通过DeepSeek提升个人在公文写作、文档处理、知识搜索、论文写作等方面的工作效率;④探索大模型在特定行业的应用潜力,如医疗、金融等领域。 其他说明:本文不仅提供了理论知识,还结合实际案例,详细介绍了DeepSeek在各个场景下的应用方式,帮助读者更好地理解和应用大模型技术。同时,文章也指出了当前大模型技术面临的挑战,如模型的局限性和数据安全问题,鼓励读者关注技术的持续改进和发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值