商品价值相等问题

文章讲述了如何通过两种操作(价值增加或减少2且免费,或价值增加或减少1但需花费1元)使得N种商品价值相等,同时消耗的金钱最少。主要策略是通过免费操作尽量让所有商品价值接近,然后对数量多的一类进行一次1元操作使其与数量少的一类匹配。提供的C++代码示例展示了如何计算这个最小花费。

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

题目:给出N种商品,第i个商品价值为Ai,现在想让他们价值相等。你可以有如下两种操作,每个商品的价值你操作任意次。

操作1:将一种商品的价格提高或减少2,并且该操作是免费的。

操作2:将一种商品的价格提高或减少1,但是该操作要消耗1块钱

你的任务是找出使所有商品相等并且消耗的钱最少。

数据范围:

1<=N<=10^5

1<Ai<=10^5

输入格式

N

A1,A2.....An

输出格式:

一个正整数表示消耗最少的钱

输入输出样例:

输入:

3
1 2 3

输出:

1


分析:

读题可知,每个商品价值都可以进行任意次操作(操作1或操作2)最终使得:

1.每个商品价值相等

2.所消耗的费用最少

题目已经明确说明:我们可对每个商品的价值操作若干次,意思就是说每个商品的价值是可以进行任意次修改的。若要保证修改的同时消耗的金钱最少,那我们可以先通过进行任意次免费的操作使得每个商品的价值统一趋向于某一个尽可能相近或者集中的区间,然后再进行价值统一操作

那么具体应该怎么做呢?

我们可以发现,输入的N个商品的价值无非就是奇数和偶数两种情况。在进行若干次免费操作(操作1)之后,每个商品的价值进行一定程度的累加或累减2之后,都可以转化成相差为1的两种取值。

在这里我们只讨论对N个商品的价值进行若干个累减2的操作情况:首先对输入的N个商品的价值作奇偶判断,将商品的价值分为奇数和偶数两类情况。所有的偶数经过若干次免费的操作最终都可以变成0,所有的奇数经过若干次免费的操作最终都可以变成1。这时候我们就只需要讨论是让0变成1还是让0变成1花费的金钱比较少。其实本质上也就是判断是奇数多还是偶数多,数量多的那方的商品价值变成另一方需要统一成的价值。

以本题的测试用例来说,输入的3个商品的价值分别为1、2、3,其中偶数为2,奇数为1、3。偶数可以经过若干次累减2变成0(免费),奇数可以经过若干次累减2变成1(免费)。但由于奇数的数量>偶数的数量,所以我们选择让偶数全部进行将商品的价格提升1(操作2),最终变成1(花费=1*偶数数量),奇数不进行改动。最终总的消费为1。

简言之,就是数量多的那方在进行完若干次操作1后固定不动,即不需要对它们进行操作。数量少的那方进行加1或者减1的操作(看成是数量多的花费为0,数量少的花费为1*数量少的那方的实际数目,总花费=1*数量少的那方的数目)。

C++代码实现:

#include<iostream>
using namespace std;

int a[100000];

int main()
{
	int N,on=0,en=0;
	cin>>N;//输入需要输入的商品价值的个数
	for(int i=0;i<N;i++)
	{
		cin>>a[i];
		if(a[i]%2!=0)
		{
			on++;
		}
		else
		{
			en++;
		}
	}
//如果是奇数数目大于偶数数目,输出偶数数目,否则,输出奇数数目:
	if(on>en)
	{
		cout<<en<<endl;
	}
	else
	{
		cout<<on<<endl;
	}

	return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

From_Zero_ to_Hero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值