当前位置:   article > 正文

贪心并不难,难的是证明。_贪心算法并不难,难的是证明。

贪心算法并不难,难的是证明。

贪心并不难,难的是证明。 贪心并不难,难的是证明。 贪心并不难,难的是证明。
                                                                                                                                                     ———— heidoudou

基本思路:先将数组 s o r t sort sort一遍,然后用双指针i = 1j = n i f ( a i + a j > w ) if(a_i+a_j>w) if(ai+aj>w),则将 a j a_j aj单独分为一组,--j e l s e else else则将 a i a_i ai a j a_j aj分为一组,++i--j

证明:

  1. i f ( a i + a j > w ) if(a_i+a_j>w) if(ai+aj>w) a j a_j aj也不可能和其他任何一个 a k ( i < k < j ) a_k(i<k<j) ak(i<k<j)为一组 → \to a j a_j aj单独一组
  2. i f ( a i + a j ≤ w ) if(a_i+a_j≤w) if(ai+ajw){
            i f if if a i a_i ai a j a_j aj各为一组,那么就会比 a i a_i ai a j a_j aj为一组的情况多出一组;
            e l s e else else i f if if a i a_i ai单独一组, a j a_j aj与另一个 a k a_k ak为一组,那么 a j a_j aj a k & a i a_k\And a_i ak&ai的组数 = a j = a_j =aj a i & a k a_i\And a_k ai&ak的组数;
            e l s e else else i f if if a j a_j aj单独一组, a i a_i ai与另一个 a k a_k ak为一组,那么 a i a_i ai a k & a j a_k\And a_j ak&aj的组数 = a i = a_i =ai a j & a k a_j\And a_k aj&ak的组数;
            e l s e else else i f if if a i a_i ai a k a_k ak a j a_j aj a m a_m am为一组,交换 a k & a j a_k \And a_j ak&aj后,    ⟹    a i + a j ≤ w \implies a_i+a_j≤w ai+ajw a k + a m ≤ a k + a j ≤ w    ⟹    a_k+a_m≤a_k+a_j≤w \implies ak+amak+ajw
            a i a_i ai a k & a j a_k\And a_j ak&aj a m a_m am的组数 = a i = a_i =ai a j & a k a_j\And a_k aj&ak a m a_m am的组数;
    }
    ∴ ∴ 我们证明看子问题的最优解可以通过上述贪心过程得到

下面我们证明贪心后 ∑ ∑ 子问题的最优解就是全局最优解

a [ i . . . j ] a[i...j] a[i...j]问题为 P P P P P P的贪心解为 S S S,经过贪心之后, ∑ ∑ 子问题 P ′ P' P的最优解为 S ′ S' S。如果 ∑ ∑ 子问题 P ′ P' P的最优解 S ′ S' S不是 P P P的最优解,那么我们先假设存在一个最优解 Z Z Z,可以通过上述证明过程后,使之变成相同 ∑ ∑ 子问题 P ′ P' P的解 Z ′ Z' Z,又 ∵ S > Z ∵S>Z S>Z,而且二者贪心后的分组数是相同的, ∴ ∴ S ′ > Z ′ S'>Z' S>Z,这就与 S ′ S' S为最优解相矛盾, → ∑ \to∑ 子问题的最优解 = = = 全局最优解

证毕 . 证毕. 证毕.

光知道贪心,贪心为什么可以得到最优解,你证明过么? 光知道贪心,贪心为什么可以得到最优解,你证明过么? 光知道贪心,贪心为什么可以得到最优解,你证明过么?
                                                                                                                                                     ———— heidoudou

#include<bits/stdc++.h>
#define ll long long
#define maxn 30005
using namespace std;
inline int read(){
	int x = 0; bool f = false; char ch = getchar();
	while(!isdigit(ch)){if(ch == '-') f = true; ch = getchar();}
	while(isdigit(ch)){x = x * 10 + ch - '0'; ch = getchar();}
	return f ? -x : x;
}
inline void write(ll x){
	if (x < 0) x = ~x + 1, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
int w, n, p[maxn], ans;
int main(){
	w = read(); n = read();
	for(register int i = 1; i <= n; ++i) p[i] = read();
	sort(p + 1, p + n + 1);
	int i = 1, j = n;
	while(i <= j){
		if(p[i] + p[j] > w){++ans; --j;}
		else{++ans; ++i; --j;}
	}
	write(ans); puts("");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号