贪心

很久没写博客了很惭愧

贪心在《算法导论》上竟然排在动态规划后面

贪心的基本思想:先把问题分成若干步骤,再在完成一个问题的每一步中,都选择局部最优解,最后导致全局最优解。

听起来很简单,但是贪心需要严格的证明。

洛谷p1094纪念品分组

由于一组最多两个物品,所以考虑尽量更多利用空间。

对于已排好序的a[1],a[2].....a[n-1],a[n],对于a[1],将它与可以安排的最大的物品安排在一起,一定是最优的。

否则可能导致这个最大的物品没有别的物品搭配而多出一组。

#include
using namespace std;
int a[30005];
bool my(int a,int b)
{
	return(a>=b);
} 
int main()
{
    int w,n;
	scanf("%d%d",&w,&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	sort(a+1,a+n+1,my);
	int i=1,j=n;
	int sum=0;
	while(i<=j)
	{
		if(a[i]+a[j]<=w)//如果能放一起,则一起放
		{
			sum++;
			i++;
			j--;
		}
		else//如果不能放一起,则大的单独放
		{
			sum++;
			i++;
		}
	}
	printf("%d",sum);
	return 0;
}

洛谷p1791线段覆盖

算导上有严格的证明,但是它从dp引到贪心我根本看不懂

直接贴做法吧......首先将线段端点调整为左端点<=右端点;然后根据右端点从小到大排序;第三,扫描一遍,遇到与当前最后的线段相交则删去,否则选择它并且设为当前最后的线段。

#include
using namespace std;
struct line
{
	int begin,end;
};
line a[1000];
bool mycmp(line a1,line b1)
{
	return(a1.end<=b1.end);
}

int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
	    scanf("%d%d",&a[i].begin,&a[i].end);
	    if(a[i].begin>a[i].end)
		{
		        int k=a[i].begin;
			a[i].begin=a[i].end;
			a[i].end=k;
		}
	}
	sort(a+1,a+n+1,mycmp);//根据右端点排序
	line t;
	int s=n;
	t.end=a[1].end;
	for(int i=2;i<=n;i++)
	{
		if(a[i].begin


你可能感兴趣的:(贪心)