1. 程式人生 > 實用技巧 >青藤程式設計營——提高組基礎專題二(貪心)

青藤程式設計營——提高組基礎專題二(貪心)

0.說點閒話

所以我現在弱到貪心都不會做了?啊這。。。。。。

1.概述

貪心,是一種只考慮區域性最優,而不顧全域性最優的演算法。

這類演算法通常思維性比較強,程式碼量比較短,適合拿來考思維。

基本上的貪心題目都要排序。

而且貪心經常容易和 dp 混淆(當然有了一定水平之後就不會混淆了)。

貪心的題目型別有很多,但是不管哪種型別的題目平常做之前我們都要嚴謹證明一遍貪心法的正確性。當然考場上用就行了,實在不會證不管他。

2.例題

題單:

A - Cleaning Shifts[OpenJ_Bailian - 2376]

題目大意:給你 \(n\) 段區間,從中取出最少的區間使得這些區間能完全覆蓋 \([1,t]\),求個數。\(1 \leq n \leq 25000,1 \leq t \leq 1000000\)

解法:區間覆蓋問題。

按照左端點升序排序,先把第一個區間取來,然後求 \(\max_{i \in [1,n] \& l_i \leq r_i}{r_i}\)

,更新右端點然後重複執行上述操作,重複時之前統計過的區間不再統計。

程式碼:

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 25000 + 10;
int n, t;
struct node
{
	int l, r;
}a[MAXN];

int read()
{
	int sum = 0, fh = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {if (ch == '-') fh = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9') {sum = (sum << 3) + (sum << 1) + (ch ^ 48); ch = getchar();}
	return sum * fh;
}

bool cmp(node fir, node sec) {return fir.l < sec.l;}

int main()
{
	n = read(); t = read();
	for (int i = 1; i <= n; ++i) {a[i].l = read(); a[i].r = read();}
	sort(a + 1, a + n + 1, cmp);
	int j = 1, p = 0, ans = 0;
	for (int i = 1; i <= n; i = j)
	{
		int r = 0;
		while (j <= n && a[j].l <= p + 1) r = max(r, a[j++].r);
		if (!r) break;
		p = r;
		ans++;
		if (r >= t) break;
	}
	if (p < t) printf("-1\n");
	else printf("%d\n", ans);
	return 0;
}

B - 今年暑假不AC[HDU - 2037]

題目大意:給你 \(n\) 個區間,保證在 \([1,n]\) 範圍內,從中選出儘量多的無交集區間。\(1 \leq n \leq 100\)

解法:最多區間問題。

按照右端點排序,然後一個一個選過去即可,每次記錄最右邊的點,有交集不選,無交集就選。

程式碼:

#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;

const int MAXN = 100 + 10;
int n, ans;
struct node
{
	int l, r;
}a[MAXN];

int read()
{
	int sum = 0, fh = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {if (ch == '-') fh = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9') {sum = (sum << 3) + (sum << 1) + (ch ^ 48); ch = getchar();}
	return sum * fh;
}

bool cmp(const node &fir, const node &sec)
{
	if (fir.r ^ sec.r) return fir.r < sec.r;
	return fir.l < sec.l;
}

int main()
{
	while ((n = read()) != 0)
	{
		for (int i = 1; i <= n; ++i) {a[i].l = read(); a[i].r = read();}
		sort(a + 1 ,a + n + 1, cmp);
		int las = a[1].r, ans = 1;
		for (int i = 2; i <= n; ++i)
		{
			if (a[i].l >= las)
			{
				las = a[i].r;
				ans++;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}

C - Radar Installation[POJ - 1328]

咕咕咕~

D - Best Cow Line[POJ - 3617]

咕咕咕~

E - Task[HDU - 4864]

咕咕咕~

F - Tian Ji -- The Horse Racing[HDU - 1052]

咕咕咕~

3.總結

咕咕咕~