#include<iostream>
#include<algorithm>
using namespace std;
#include<vector>
#include<string>
/*贪心算法*/ //:一般是计算一个最大值或者最小值,(注意与dp分开)局部最优为全局最优
//1.问题描述:给一个字符串数组,返回其拼接后的最小字典序
class MyCompare {
public:
bool operator()(string a, string b) {
return (a + b).compare(b + a) == -1 ? true : false;
}
};
string processing(vector<string>arr) {
if (arr.size() == 0) return "";
sort(arr.begin(), arr.end(),MyCompare());
string ans = "";
for (string str : arr) {
ans += str;
}
return ans;
}
//2.给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
//设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
// 只要后天比前一天有赚,就买(不是每2天,是每一天eg:1,2,3 1买2卖赚1, 2买3卖赚1 共赚2)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int profit = 0;
for (int i = 1; i<prices.size(); i++) {
if (prices[i]>prices[i - 1]) {
profit += prices[i] - prices[i - 1];
}
}
return profit;
}
};
//问题描述:children的饥饿度数组,cookies:饼干大小 每个孩子只能
//吃一个饼干或者不吃,求解最多有多少孩子可以吃饱
//思路:优先满足饥饿度最小的孩子
class Solution1{
public:
int processing(vector<int>children, vector<int>cookies) {
sort(children.begin(), children.end());
sort(cookies.begin(), cookies.end());
int childcaneat = 0;
int cookiesnum = 0;
while (childcaneat < children.size() && cookiesnum < cookies.size()) {
if (children[childcaneat] <= cookies[cookiesnum++]) childcaneat++;
}
return childcaneat;
}
};
//问题描述:区间问题:给定多个区间,计算这些区间互不重叠的区间的最大个数,起止相连不算重叠
// 问题变种:老板会议时间规划为给定的多个区间,计算老板最多开的会议数量
class Mycom{
public:
bool operator()(vector<int>a,vector<int>b){
return a[1] < b[1];
}
};
class Solution2 {
public:
int processing(vector<vector<int>>arr){
sort(arr.begin(), arr.end(), Mycom());
int countnum = 1;
int pre = arr[0][1];
for (int i = 1; i < arr.size(); i++) {
if (arr[i][0] >= pre) {
countnum++;
pre = arr[i][1];
}
}
return countnum;
}
};
int main() {
//vector<string>arr = { "ba", "b", "de", "c" };
//cout << processing(arr) << endl;
vector<vector<int>>arr = { { 2, 4 }, { 1, 2 }, {2,3}, { 3, 4 } };
Solution2 slt;
cout<<slt.processing(arr);
system("pause");
return 0;
}
//问题描述:给定一个数组,例如【10,20,30】表示要把一块长度为10+20+30=60的黄金分成
//10,20,30 总3块,在每次划分中60---->10 + 50 就需要10+50的体力值消耗,50--->
//20+30 就需要20+30的体力值消耗,2次总共消耗110体力值,采用某种方法的最小体力值消耗为多少?
//思路,贪心+小根堆,把【10,20,30】压入小根堆,弹出10和20,相加为30,再压入小根堆,弹出30和30
#include<iostream>
#include<vector>
using namespace std;
#include<string>
#include<algorithm>
#include<queue>
#include<functional>
int main() {
vector<int>arr = { 10, 20, 30 };
priority_queue<int, vector<int>, greater<int> >a;
for (int i = 0; i < arr.size(); i++) {
a.push(arr[i]);
}
int sum = 0;
int cur = 0;
int firstnum = 0;
int secondnum = 0;
while (a.size()>1) {
firstnum = a.top();
a.pop();
secondnum = a.top();
a.pop();
cur = firstnum + secondnum;
sum += cur;
a.push(cur);
}
cout << sum << endl;
system("pause");
return 0;
}
//问题描述:投资项目,项目净收入数组profit和项目花费数组cost,投资次数times,启动资金startmoney,问获利的最大值
思路:先入小根堆(cost小到大) 在符合条件的如大根堆
#include<iostream>
#include<vector>
using namespace std;
#include<string>
#include<algorithm>
#include<queue>
#include<functional>
struct Node {
int m_profit;
int m_cost;
Node() {}
Node(int profit, int cost) : m_profit(profit), m_cost(cost) {}
};
struct MyCompareless {
bool operator()(Node a,Node b) {
return a.m_cost > b.m_cost;
}
};
struct MyComparegreator {
bool operator()(Node& a, Node& b) {
return a.m_profit < b.m_profit;
}
};
class Solution {
public:
int func(vector<int>profit, vector<int>cost, int startmoney, int times) {
priority_queue<Node, vector<Node>, MyCompareless>a;
priority_queue<Node, vector<Node>, MyComparegreator>b;
Node temp;
for (int i = 0; i < profit.size(); i++) {
temp = Node(profit[i], cost[i]);
a.push(temp);
}
for (int i = 0; i < times; i++) {
while (!a.empty()) {
Node temp = a.top();
if (temp.m_cost <= startmoney) {
b.push(temp);
a.pop();
}
else {
break;
}
}
if (b.empty()) return startmoney;
startmoney += b.top().m_profit;
b.pop();
}
return startmoney;
}
};
int main() {
vector<int>profit = { 1, 4, 3 };
vector<int>cost = { 1, 1, 2 };
Solution slt;
cout << slt.func(profit,cost,1,2) << endl;
system("pause");
return 0;
}
tip: 优先队列的默认顺序是大到小,所以在重新排序函数时,与以前的sort等不一样