题目:给出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;
}