做游戏

题目描述
m个小学生在一起做游戏。这些同学分别来自n个不同的学校。现在要进行这样一个非常好玩的游戏,首先要把同学们分成若干组,每组两个同学,并且每个组中的同学来自不同的学校,剩下的同学不能加入游戏。现在,我们要使剩下不能参加游戏的同学最少。请你帮忙求出最多能组成多少组学生玩游戏。

输入
两行 第一行:n m  n个不同的学校,m个小学生
第二行:a1 a2 a3 …an  

输出
一个整数,表示最多多少组学生玩游戏

样例输入
样例输入1
3 9
2 4 3
样例输入2
3 11
2 6 3

样例输出
样例输出1
4
样例输出2
5
数据范围限制
N<=100000,m<=1000000

这一题有两种做法,一种是数学方法,第二种是用DP来做。两种方法都能拿满分。

数学方法

我们定义ax值用来存a数组里的最大值,判断如果最大值与总和的差比最大值要大,就输出总和整除2的结果,否则判断如果最大值与总和的差是否比最大值要小,输出最大值与总和的差。

核心代码
if(m-ax>ax)
{
	printf("%d",m/2);//最大值与总和的差比最大值要大
}
else if(m-ax<ax)
{
	printf("%d",m-ax);//最大值与总和的差比最大值要小
}

DP方法

f[i]表示i*2个人最多多少组学生玩游戏。
第一层循环枚举1~n,第二层循环枚举m/2到第i个学校的人数。
如果f[j-a[i]]]+a[i]大于f[j]那么f[j]赋值为f[j-a[i]]+a[i]。
动态转移方程就是if(f[j-a[i]]+a[i]>f[j])f[j]=f[j-a[i]]+a[i];

核心代码
for(int i=1;i<=n;i++)
	{
		for(int j=s/2;j>=a[i];j--)
		{
			if(f[j-a[i]]+a[i]>f[j])
				f[j]=f[j-a[i]]+a[i];
		}
	}
代码信息
方法一
时间复杂度总时间
Θ(n)n
方法二
时间复杂度总时间
Θ(nm)n(m/2-a[i])
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值