贪心法基本概念
在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。----百度百科
在我看来贪心算法的核心就是要捋清一个问题的核心所在,即产生结果的关键原理根据这个原理做出解答,从而达到局部影响关键的作用,个人感觉题就是看着看着写着写着就会了,原理没啥用
贪心法的解题思路
- 建立数学模型来描述问题
- 把求解的问题分成若干个子问题
- 对每个子问题求解,得到子问题的局部最优解
- 把子问题的解局部最优解合成原来问题的一个解
(注*:贪心的思路是从局部开始考虑最优解,但有些时候局部的贪婪不能统筹兼顾问题的各个要素,只能满足一些特定条件的问题。emm。。。会WA但是不一定完全WA)
贪心法适用的问题
U1S1:由于贪心法的局部性,真正能够贪心出来的题很少。要对问题的几个数据(非特殊)进行分析,找出规律后再莽
贪心选择策略
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。----简书
例题
选自codeforces的div3 B
题目大意
题意相对不好理解(不是我语文垃圾 )
大致是说有一堆字符串和红绿两种颜色的油漆,对字符进行涂色要满足三个条件
- 每个字符可以涂色或者不涂
- 相同字符不能涂一样的颜色(不涂色的不视作一种颜色)
- 最后红和绿的数量必须一致
解题思路
统计所有字符出现的数量,如果数量大于2直接染色,并且计数++,最后将所有数量小于2的字符数量相加整除2将结果加到计数上。
原理很简单(废话div3呢):因为红和绿都要染色并且一种字符只能染一种颜色,红绿又要样数量。所以大于等于2的时候正好雨露均沾。对于那些零散的只要整除2就可
(忽略我又臭又长的头文件)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <string>
#include <functional>
#include <cstring>
#include <cctype>
#include <stack>
#include <queue>
#include <set>
#define IOS() std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
typedef long long ll;
using namespace std;
int mapp[30];
int main()
{
IOS();
int t;
cin>>t;
while(t--){
string s;
cin>>s;
int len=s.length();
memset(mapp,0,sizeof(mapp));
for(int i=0;i<len;i++){
mapp[s[i]-'a']++;
}
int sum=0;
int ans=0;
for(int i=0;i<30;i++){
if(mapp[i]>=2) {
sum++;
ans+=mapp[i];
}
}
cout<<sum+(len-ans)/2<<endl;
}
return 0;
}