第十周小结

  这周主要看了贪心算法,贪心算法用于求最优解,他将复杂问题分解成一个个小问题,求出每个小问题的最优解,最终一步步得到了整个问题的最优解。可以看出贪心是通过求局部最优得到整体最优解。

  一、看了有关贪心的博客,感觉用贪心解决问题的核心是找到贪心标准。举个例子:
【ctsc2007】【挂缀】

题意:第i个挂缀满足下方所有珠缀的重量和不超过承重能力k,求最长可能的稳定挂缀,若多个可选方案,求总重量最小的。

分析:
  珠子越往下重量越少,若想满足承重能力k,可以将承重能力大的往上放,小的往下放;因为越下面的珠子被计算重量的次数越多,为了不超过k,可以将重量大的往上放,由此我们可以发现此题的贪心标准:比较珠子的承重能力c与重量w之和的大小。按c+w从小到大排序,从底下往上挂,若承重满足下面重量就挂上,否则删去继续挂,最后得到最长的稳定挂缀。
  找到正确的贪心标准是解题的重点,每个题的贪心标准不同,我们需要从题干中寻找信息。

  二、

Canada Cup 2016 F. Family Photos

题意:
给出n对照片,Alice和Bonnie轮流取照片,每张照片有两个值a 和 b ,a表示Alice取走这张照片获得的喜悦值,b表示Bonnie取走这张照片获得的喜悦值,当轮到一个人时,他可以选择不取,当连续两轮两个人都不取时,游戏结束,Alice和Bonnie喜悦值差值最大的方案。

题解:
分类讨论,若a1<=b2&&b1<=a2,双方第一次选择均为负收益,忽略即可。非1情况下若a1+b1<=a2+b2, 双方后都是选好于先选。其余他情况下其余物品可以正常选择。物品的价值可以看做ai+bi,优先队列加贪心进行选择。

【bzoj1034】【zjoi2008】【泡泡堂】

题意:每胜一场比赛得2分,平一场得1分,输一场不得分,分别求最好与最坏的情况下的得分。

题解:
这题和田忌赛马很类似。田忌赛马的思想主要是:
  如果田忌目前的最快马快于齐王目前的最快马,则两者比;如果田忌的最快马慢于齐王的最快马,则用田忌的最慢马与齐王的最快马比;如果田忌的最快马和齐王的最快马相等,则分两种情况:若田忌的最慢马快与齐王的最慢马,两者比,否则用田忌的最慢马与齐王的最快马比。

这题与之相似但不完全相同。如果最弱的能赢对方最弱的就赢,否则最强的能赢对面最强的就赢,否则最弱的换对面最强。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
int a[N], b[N];
int i, j, x, y;
long long ans = 0;
bool cmp(int u, int v)
{  return u > v; }
int main()
{   cin>>n;
	for(int i = 1; i <= n; i++) cin>>a[i];
	for(int i = 1; i <= n; i++) cin>>b[i];
	sort(a + 1, a + 1 + n, cmp);
	sort(b + 1, b + 1 + n, cmp);
	i = 1, j = n; x = 1, y = n;
	for(int k = 1; k <= n; k++)
	{
		if(a[i] > b[x])
		{   ans += 2;
			i++, x++;
		}
		else if(a[j] > b[y])
		{   ans += 2;
			j--, y--;
		}
		else
		{   if(a[j] >= b[x])
				ans += 1;
			j--, x++;
		}
	}
	printf("%lld ", ans);
	i = 1, j = n; x = 1, y = n;
	ans = 0;
	for(int k = 1; k <= n; k++)
	{
		if(b[i] > a[x])
		{  i++, x++; }
		else if(b[j] > a[y])
		{  j--, y--; }
		else
		{   if(b[j] < a[x])  ans += 2;
			else   ans += 1;
			j--, x++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

P4157 [SCOI2006]整数划分

题意:要求将n写成若干个正整数之和,并且使这些正整数的乘积最大。

题解:
看这道题的题解时,看到这题的解法是选尽量多的3,余下用2补。不是很理解这种做法,于是去查资料,在洛谷题解中找到了以下解答。

洛谷上的题解:

对于给定的正整数n>2,为了将n写成若干个正整数之和,并且使这些正整数的乘积最大。只须将
n写成若干个2与3的和,并满足:2p+3q=n.其中 q=(n-2p)/3。

人家是这么证明的:
设a是将n做最大乘积分解后的任一项,下面证2≤a≤4。
若a=1,设b是将n做最优分解后的另一项,则 ab=1b=b<1+b,即把a,b合并为一项后,总乘积会更大,故必有2≤a。
若a≥5,则容易证明这时成立:a<3(a-3),即把a分解为两项:3与a-3之后,总和不变,而总乘积会更大,故必有a≤4。
由于4=2*2=2+2,因此最优分解中,可用2个2代替1个4。又由于2+2+2=3+3,而2 * 2 * 2<3 * 3,因此3个2应该用2个3代替。

看完后恍然大悟,原来这道题可以有这样的思路,看来我还是知识面太窄,果然还是多多积累,多学多思多用。

  三、这周还讲了一点动态规划。动态规划是分阶段求最优值的算法,和贪心一样将复杂问题划分为子问题。区别在于:1.贪心算法是自顶向下的,而动态规划则是自底向上的。2.动态规划是自底向上将子问题解决,一步步解到最后得到问题的全局最优解。贪心不能保证求得的最后解是最佳的,而动态规划是通过一些状态来描述一些子问题,然后通过状态之间的转移来求解,其解一定是最优解。现在只领会这些区别,下周会加强对dp的练习,后续会再补充一些有关总结。

四、这周因为有考试,对贪心投入的精力少了,感觉自己没有把这部分理解透彻,下周再接再厉,正好与动态规划对比着学习,加强对贪心的掌握。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值