贪心算法
万里不惜死,一朝得成功
区间选点
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool compareb(pair<int,int> &a, pair<int,int> &b){
return a.second < b.second;
}
// 贪心算法
int main()
{
int n;
cin >> n;
vector<pair<int,int>> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i].first >> A[i].second;
}
sort(A.begin(), A.end(), compareb);
int res = 1;
int lastr = A[0].second;
int l,r;
// 排序后,不断遍历,如果这次的左小于上次的右就还可以有交点,如果大于就+1然后更新右
for (int i = 1 ; i < n; i ++ ){
l = A[i].first;
r = A[i].second;
if(l > lastr){
res ++;
lastr = r;
}
}
cout << res;
return 0;
}
最大不相交区间
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool compareb(pair<int,int> &a, pair<int,int> &b){
return a.second < b.second;
}
int main()
{
int n;
cin >> n;
vector<pair<int,int>> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i].first >>A[i].second;
}
sort(A.begin(),A.end(),compareb);
int res = 1;
int lastr = A[0].second;
int l,r;
//类似选点
for (int i = 1; i < n; i ++ ){
l = A[i].first;
r = A[i].second;
if(l > lastr){
res ++;
lastr = r;
}
}
cout << res;
return 0;
}
区间分组
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool compareb(pair<int,int> &a, pair<int,int> &b){
return a.first < b.first;//这次是用起点排序
}
int main()
{
int n;
cin >> n;
vector<pair<int,int>> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i].first >>A[i].second;
}
sort(A.begin(),A.end(),compareb);
int res = 0;
int lastr = -1e9-1;
int l,r;
vector<bool> visit(n,false);
for (int j = 0; j < n; j ++ ){
if(!visit[j]){//如果尚未记录就可以走
visit[j] = true;
res++;
lastr = A[j].second;
for (int i = j+1; i < n; i ++ ){
if(!visit[i]){
l = A[i].first;
r = A[i].second;
if(l > lastr){
lastr = r;
visit[i] = true;
}
}
}
}
}
cout << res;
return 0;
}
自己写了一个超时方法。
优化了一下还是不行
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool compareb(pair<int,int> &a, pair<int,int> &b){
return a.first < b.first;//这次是用起点排序
}
int main()
{
int n;
cin >> n;
vector<pair<int,int>> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i].first >>A[i].second;
}
sort(A.begin(),A.end(),compareb);
int res = 0;
int lastr = -1e9-1;
int l,r;
vector<bool> visit(n,false);
int j = 0;
bool flag = true;
while(j<n){//实际上O(n)?
flag = true;//确保每次更新的都是最小的那个非同区间
if(!visit[j]){//如果尚未记录就可以走
visit[j] = true;
res++;
lastr = A[j].second;
for (int i = j+1; i < n; i ++ ){
if(!visit[i]){
l = A[i].first;
r = A[i].second;
if(l > lastr){
lastr = r;
visit[i] = true;
}else if(flag){
j = i;
flag = false;
}
}
}
}else{
j++;
}
}
cout << res;
return 0;
}
区间分组
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int main()
{
int n;
cin >> n;
vector<pair<int,int>> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i].first >> A[i].second;
}
sort(A.begin(), A.end());
// greater反过来是less
priority_queue<int, vector<int>, greater<int>> min_heap;
int l,r;
for (auto x: A){
l = x.first;
r = x.second;
if(!min_heap.empty()&&min_heap.top()< l){
min_heap.pop();//因为是经过排序的,如果l比上一个r大,说明不是相交的一组
//那么把他弹出换成现在的r,才能正确下一次比较
}
min_heap.push(r);
}
cout << min_heap.size();
return 0;
}
区域覆盖
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int,int> PII;
bool compareb(PII&a,PII&b){
return a.second < b.second;
}
int main()
{
PII tar;
cin >> tar.first >> tar.second;
int n;
cin >> n;
vector<PII> A(n);
int a,b;
for (int i = 0; i < n; i ++ ){
cin >> a >> b;
if(a>tar.second||b<tar.first)continue;
A[i].first = a;
A[i].second = b;
}
sort(A.begin(), A.end());
//当前区间
int len = A.size();
int maxs = tar.first;
int curs = tar.first;
int i = 0;
int res = 0;
//贪心算法
while(curs < tar.second){//用这个保证再循环捏判断
while(i<len&&A[i].first<=curs){//数组不越界,更新边界
maxs = max(maxs, A[i].second);
i++;
}
if(curs == maxs){//maxs无法更新,说明没了
cout << -1;
return 0;
}
curs = maxs;//突破了边界,进入下一个边界
res ++;
if(curs >= tar.second){//相等边界
cout << res;
return 0;
}
}
for(auto x:A){//针对单点的情况
int a = x.first;
int b = x.second;
if(a<=tar.first&&b>=tar.second){
cout << 1;
return 0;
}
}
//都不能就没了
cout << -1;
return 0;
}
哈夫曼树
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i];
}
sort(A.begin(),A.end());
int temp;
long long sum = 0;
while(A.size()>1){
A[0] = A[0] + A[1];
sum += A[0];
auto it = A.erase(A.begin()+1);
sort(A.begin(),A.end());
}
cout << sum;
return 0;
}
第一个做法,每次加完就排序。
还有一个小根堆做法。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int main()
{
int n;
cin >> n;
int a;
//最小堆
priority_queue<int, vector<int>, greater<int>> min_heap;
for (int i = 0; i < n; i ++ ){
cin >> a;
min_heap.push(a);
}
int x,y;
int sum = 0;
while(min_heap.size()>1){
x = min_heap.top();
min_heap.pop();
y = min_heap.top();
min_heap.pop();
x = x + y;
sum += x;
min_heap.push(x);
}
cout << sum;
return 0;
}
排队打水
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
int main()
{
int n;
cin >> n;
int a;
priority_queue<int, vector<int>, greater<int>> h;
for (int i = 0; i < n; i ++ ){
cin >> a;
h.push(a);
}
long long sum = 0;
int x,t=0;
while(h.size()>0){//注意这里是排队打水获得等待时间
x = h.top(); h.pop();
sum += t;
t += x;
}
cout << sum;
return 0;
}
仓库选地址
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
//多组数据要清空
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i];
}
vector<int> B = A;
sort(A.begin(), A.end());
// 找中位数~
int mid;
if(n % 2 == 0){
mid = A[n/2]+A[(n/2) - 1];
mid /= 2;
}else{
mid = A[n/2];
}
int sum = 0;
for (int i = 0; i < n; i ++ ){
sum += abs(mid - B[i]);
}
cout << sum;
return 0;
}
堆牛
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
//注意预设负无穷正无穷,数据复杂!
//注意使用longlong!!
//明天整理板子
using namespace std;
typedef pair<int, int> PII;
// 重的和承重厉害的都应该在下面,直接加起来不就好了。。
bool compareb(PII&a,PII&b){
return a.second+a.first > b.second+b.first;
}
int main()
{
int n;
cin >> n;
vector<PII> A(n);
for (int i = 0; i < n; i ++ ){
cin >> A[i].first >> A[i].second;
}
sort(A.begin(), A.end(), compareb);
// 题目还要求是必须是最大值。。要注意题目啊
int maxe = -0x3f3f3f3f;//预设用这个才对
for (int i = 0; i < n; i ++ ){
int weight = 0;
for (int j = i+1; j < n; j ++ ){
weight += A[j].first;
}
maxe = max(maxe, weight - A[i].second);
}
cout <<maxe<<endl;
return 0;
}
浙公网安备 33010602011771号