首先要明确一个概念:最优子结构的性质是什么?
即当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质.
贪心算法的定义 百度词条的定义:
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
解题的一般步骤是:
1.建立数学模型来描述问题;
2.把求解的问题分成若干个子问题;
3.对每一子问题求解,得到子问题的局部最优解;
4.把子问题的局部最优解合成原来问题的一个解。
AcWing_110.防晒
问题可以抽象成给定一些区间和一些有重复的点,若点包含于区间则匹配成功,求最大匹配数,即二分图的匹配问题。首先,可以按左端点降序排序,然后将各点也降序排序。因为对于每一头奶牛而言,当然是要选择目前来说满足条件的最差的防晒霜,而最差的定义,就是选择满足奶牛条件的SPF最大的那一瓶防晒霜.
为什么降序排序?因为要保证对于每一头奶牛而言,它用的是当前可以使用的最差的防晒霜,因为值越小的防晒霜,有可能让更多的牛使用。
Java代码(贪心+自定义排序规则)
import java.util.Arrays;
import java.util.Scanner;
class SpfCover implements Comparable<SpfCover>{
int spf,cover;
public SpfCover(int spf, int cover) {
this.spf = spf;
this.cover = cover;
}
@Override
public int compareTo(SpfCover o) {
if(spf == o.spf)
return o.cover - this.cover;
return o.spf - this.spf;
}
}
class SPFRange implements Comparable<SPFRange>{
int minSPF,maxSPF;
public SPFRange(int minSPF, int maxSPF) {
this.minSPF = minSPF;
this.maxSPF = maxSPF;
}
@Override
public int compareTo(SPFRange o) {
if(minSPF == o.minSPF)
return o.maxSPF - this.maxSPF;
return o.minSPF - this.minSPF;
}
}
public class 防晒 {
private static Scanner sc;
public static void main(String[] args) {
sc = new Scanner(System.in);
int c = sc.nextInt();
int l = sc.nextInt();
SpfCover []sp = new SpfCover[l+1];
SPFRange []arr = new SPFRange[c+1];
for(int i=0;i<c;i++) {
int min = sc.nextInt();
int max = sc.nextInt();
arr[i] = new SPFRange(min, max);
}
for(int i=0;i<l;i++) {
int spf = sc.nextInt();
int cnt = sc.nextInt();
sp[i] = new SpfCover(spf,cnt);
}
Arrays.sort(arr,0,c);
Arrays.sort(sp,0,l);
int ans=0;
for(int i=0;i<c;i++) {
for(int j=0;j<l;j++) {
if(sp[j].spf<=arr[i].maxSPF && sp[j].spf>=arr[i].minSPF && sp[j].cover!=0) {
sp[j].cover--;
ans++;
break;
}
}
}
System.out.println(ans);
}
}
注:此题的贪心策略是对区间左端点和spf点集进行降序排列
AcWing_111.畜栏预定
y老师题解
算法步骤:
1。将所有牛按开始吃草的时间排序;
2。用小根堆维护当前所有畜栏的最后一头牛的吃草结束时间;
3。如果当前的牛可以安排在堆顶的畜栏中,则将其安排进去,否则就新建一个畜栏;
Java代码(贪心+自定义排序规则)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;
//猜测运行要3秒多,带优化
class Pair implements Comparable<Pair> {
int first, second,index;
public Pair(int first, int second,int index) {
this.first = first;
this.second = second;
this.index = index;
}
@Override
public int compareTo(Pair o) {
return first - o.first;
}
}
class Stall implements Comparable<Stall> {
int r;
ArrayList<Integer> cowId = new ArrayList<>();
int idx;
public Stall(int r, int cowId, int idx) {
this.r = r;
this.cowId.add(cowId);
this.idx = idx;
}
@Override
public int compareTo(Stall o) {
return r - o.r;
}
}
public class Main{
private static Scanner sc;
public static void main(String[] args) {
sc = new Scanner(System.in);
int n = sc.nextInt();
Pair[] cows = new Pair[n + 1];
for (int i = 0; i < n; i++) {
int l = sc.nextInt();
int r = sc.nextInt();
cows[i] = new Pair(l, r, i+1);
}
Arrays.sort(cows, 0, n);
PriorityQueue<Stall> queue = new PriorityQueue<>();
while (!queue.isEmpty())
queue.poll();
for (int i = 0; i < n; i++) {
if (queue.isEmpty() || queue.peek().r >= cows[i].first) {
Stall stall = new Stall(cows[i].second, cows[i].index, queue.size() + 1);
queue.offer(stall);
} else {
Stall stall = queue.poll();
stall.r = cows[i].second;
stall.cowId.add(cows[i].index);
queue.offer(stall);
}
}
System.out.println(queue.size());
int[] res = new int[n + 1];
while (!queue.isEmpty()) {
Stall stall = queue.poll();
for (int cowid : stall.cowId) {
res[cowid] = stall.idx;
}
}
for (int i = 1; i <= n; i++) {
System.out.println(res[i]);
}
}
}