基础贪心题选讲

题目描述

小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则:首先,比赛时间分为n个时段(n≤500),它又给出了很多小游戏,每个小游戏都必须在规定期限ti时时间段之前完成(1≤ti≤n)。
如果一个游戏没能在规定期限前完成,则要从奖励费m元中扣去一部分钱wi,wi为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时间段(要占一个单位时间)内完成,而且都必须从整时段开始。
主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!
注意:比赛绝对不会让参赛者赔钱!

输入格式

第1行为m,表示一开始奖励给每位参赛者的钱;第2行为n,表示有n个小游戏;第3行有n个数,分别表示游戏1到n的规定完成期限;第4行有n个数,分别表示游戏1到n不能在规定期限前完成的扣款数。

输出格式

仅1行。表示小伟能赢取最多的钱。

样例数据

input

10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10

output

9950

...首先,可以先将每个小游戏按扣钱数为关键字从大到小排序。对规定期限离散化(勉强这么叫吧),开一个vis数组。O(n)扫一遍,如果1-i的时间都已经被占用,则扣掉当前游戏的钱,由于已经排过序,当前游戏的扣钱数肯定比前面的扣钱数少。

	sort(a+1,a+n+1,mycmp);
	for(i=1;i<=n;i++)
	{
	    k=a[i].time;
	    while(c[k]&&k>0)k--;
	    if(k>0)c[k]=1;
	        else m-=a[i].money;
	}

题目描述

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。

你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

【限制】

50%的数据满足: 1 <=n <= 15

100%的数据满足: 1 <= n <= 30000, 80 <= W <= 200

输入格式

第1行包括一个整数w,为每组纪念品价格之和的上眼= 第2行为一个整数n,表示购来的纪念品的总件数G

第3-n+2行每行包含一个正整数Pi (5 <= Pi <= w3)w表示所对应纪念品的价格。

输出格式

仅1行,包含一个整数, ep最少的分组数目合

样例数据

input

100
9
90
20
20
30
50
60
70
80
90

output

6

数据规模与约定

时间限制:1s

空间限制: 256MB

以纪念品的价格为关键字从小到大排序

设两个指针ij,分别从头和尾扫

如果a[i] + a[j]满足题目的要求,则选择,i++ j--

如果不满足,则是过大,使j--,a[j]就会变小(已从小到大排序),继续试探是否满足要求

(我个菜B偷懒写了个O(n ^ 2),事实上只需要O(n))

(代码可能跟解释不一样,因为是O(n ^ 2)的代码(我菜),大概意思还是差不多的)

         sort(a+1,a+n+1);
	 for (i=1;i<=n;i++)
	  for (j=n;j>i;j--)
	   {
	   	if ((a[i]+a[j]<=mmax)&&(b[i])&&(b[j]))
	   	 {
	   	 	b[i]=false;
	   	 	b[j]=false;
	   	 	max++;
	   	 }
	   }

题目描述

在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没有住满。 有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。 自顶遗失以后,农民约翰必须尽快在牛棚之上竖立起新的木板。 他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板。 农民约翰想将他购买的木板总长度减到最少。 给出 M(1<= M<=50),可能买到的木板最大的数目;S(1<= S<=200),牛棚的总数;C(1 <= C <=S) 牛棚里牛的数目,和牛所在的牛棚的编号stall_number(1 <= stall_number <= S),计算拦住所有有牛的牛棚所需木板的最小总长度。 输出所需木板的最小总长度作为的答案。

输入格式

第 1 行: M , S 和 C(用空格分开) 第 2 到 C+1行: 每行包含一个整数,表示牛所占的牛棚的编号。

输出格式

单独的一行包含一个整数表示所需木板的最小总长度。

样例数据

input

4 50 18
3
4
6
8
14
15
16
17
21
25
26
27
30
31
40
41
42
43

output

25

数据规模与约定

时间限制:1s1s

空间限制:256MB256MB

注释

[ 一种最优的安排是用板拦住牛棚3-8,14-21,25-31,40-43.]

通过观察题面和样例,我们可以知道:要达到最优解,必须让可以不覆盖的范围最大

则可以先对c个牛棚以编号为关键字从小到大排序,然后求出每两个牛棚的差

存在一个数据结构(可以存在可持久化线段树里,取出1-m-1大)(还可以存在斐波那契里堆食用风味更佳)  (你要存在暴力实现可持久化的splay也没问题),然后取出最大的m - 1个数

然后就可以乱搞了

inline void init()
{
	if (m > c)
	 {
	 	printf("%d\n", c);
	 	exit( 0 );
	 }
	for (int i = 1 ; i <= c; i++)
	 a[i] = read();
	sort(a + 1 , a + c + 1);
	for (int i = 2; i <= c ; i++)
	 {
	 	long long c = (long long) ( a[i] ) - a[i - 1] - 1;
		b[++t] = c;
	 }
}

inline void work()
{
	sort(b + 1, b + t + 1);
	long long ans1 = 0;
	ans = a[c] - a[1] + 1;
	for (int i = c - 1 ;i > c - m;i--)
	 ans1 += b[i];
	printf("%lld\n", ans - ans1);
}

256M1

首先安装

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值