【NOIP普及组】1387:搭配购买(buy)

该博客介绍了如何运用并查集和0-1背包算法解决一个关于云朵购买的问题。Joe在商店中选择云朵,每朵云有价格和价值,某些云朵需要搭配购买。通过并查集处理搭配关系,然后用0-1背包求解方法找出最大价值组合,确保总价格不超过Joe的钱数。示例输入和输出展示了算法的运用。

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

【信奥赛一本通】1387:搭配购买(buy


)

1.【题目描述】

【题目描述】
Joe觉得云朵很美,决定去山上的商店买一些云朵。商店里有n朵云,云朵被编号为1,2,…,n,并且每朵云都有一个价值。但是商店老板跟他说,一些云朵要搭配来买才好,所以买一朵云则与这朵云有搭配的云都要买。

但是Joe的钱有限,所以他希望买的价值越多越好。

【输入】
第1行n,m,w,表示n朵云,m个搭配,Joe有w的钱。

第2~n+1行,每行ci,di表示i朵云的价钱和价值。

第n+2~n+1+m行,每行ui,vi,表示买ui就必须买vi,同理,如果买vi就必须买ui。

【输出】
一行,表示可以获得的最大价值。

【输入样例】
5 3 10
3 10
3 10
3 10
5 100
10 1
1 3
3 2
4 2
【输出样例】
1

2.【代码】

#include<bits/stdc++.h>
#define N 10000
using namespace std;
struct st{
	int x;//价钱 
	int y;//价值 
};
st d[N];
int f[N];//并查集 
int w[N],v[N],b[N];//0-1背包问题求解
int n,m ,w1;
int find(int x)
{
	if(f[x]==x)
	{
		return x;
	}
	else
	{
		return f[x]=find(f[x]);
	}
}
void fun(int x,int y) 
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		f[y]=x;
		d[x].x+=d[y].x;//合并商品 
		d[x].y+=d[y].y;//合并商品 
	}
}
void fun1(int *f,int n)
{
	for(int i=1;i<=n;i++)
	{
		f[i]=i;
	}
}
int main()
{
	cin>>n>>m>>w1;
	for(int i=1;i<=n;i++)
	{
		cin>>d[i].x>>d[i].y;
	}
	fun1(f,n);
	int x,y;
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		fun(x,y);
	}
	int t=0; 
	for(int i=1;i<=n;i++)//更新物品 
	{
		if(f[i]==i)
		{
			t++;
			w[t]=d[i].x;
			v[t]=d[i].y;
		}
	}
	for(int i=1;i<=t;i++)//0-1背包问题 
	{
		for(int k=w1;k>=w[i];k--)
		{
			b[k]=max(b[k],b[k-w[i]]+v[i]);
		}
	}
	cout<<b[w1];
    return 0;
}

仅供参考!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值