《算法竞赛从入门到国奖》算法基础:入门篇-贪心算法(中)

💡Yupureki:个人主页

✨个人专栏:《C++》 《算法》


🌸Yupureki🌸的简介:


目录

推公式

[1. 拼数](#1. 拼数)

算法原理

实操代码

[2. Protecting the Flowers S](#2. Protecting the Flowers S)

算法原理

实操代码

[3. 奶牛玩杂技](#3. 奶牛玩杂技)

算法原理

实操代码


推公式

1. 拼数

题目链接:

P1012 NOIP 1998 提高组 拼数 - 洛谷

算法原理

贪心算法:

我们定义 x + y = xy,例如 13 + 312 = 13312,312 + 13 = 31213

然后对数据进行排序

  1. 如果x + y > y + x,那么x放在前面,y放在后面

  2. 如果x + y < y + x,那么y放在前面,x放在后面

3 如果x + y = y + x,那么谁放在前面都无所谓

实操代码

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

bool compare(const string& a, const string& b) {
    return a + b > b + a;
}

int main()
{
    vector<string> v;
    int n; cin >> n;
    while (n--)
    {
        string s; cin >> s;
        v.push_back(s);
    }
    sort(v.begin(), v.end(),compare);
    string ret;
    for (auto& it : v)
    {
        ret += it;
    }
    cout << ret;
    return 0;
}

2. Protecting the Flowers S

题目链接:

P2878 USACO07JAN Protecting the Flowers S - 洛谷

算法原理

贪心算法:

我们对原数组排序,排完序后的顺序就是最优的选择顺序

排序原则:

我们设交换i和j两头牛的位置,当从头开始到达i位置时,花费的时间为T

交换前:

第i头牛吃草量 T * di

第j头牛吃草量 T * (2 * ti) * dj

则总吃草量 sum1 = T * di + T * dj + 2 * ti * dj

交换后:

第j头牛吃草量 T * dj

第i头牛吃草量 T * (2 * tj) * di

则总吃草量 sum2 = T * dj + T* di + 2 * tj * di

因此如果要让i在j前面,则sum1 < sum2,即ti * dj < tj * di,反之在后面

实操代码

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> T;
vector<int> D;
vector<int> v;

bool cmp(const int& x, const int& y)
{
    return T[x] * D[y] < T[y] * D[x];
}

int main()
{
    int n; cin >> n;
    long long sum = 0;
    long long ret = 0;
    for (int i = 0; i < n; i++)
    {
        int t, d; cin >> t >> d;
        T.push_back(t);
        D.push_back(d);
        v.push_back(i);
        sum += d;
    }
    sort(v.begin(), v.end(),cmp);
    for (auto& it : v)
    {
        sum -= D[it];
        ret += sum * T[it];
    }
    cout << ret * 2;
}

3. 奶牛玩杂技

题目链接:

P1842 USACO05NOV 奶牛玩杂技 - 洛谷

算法原理

贪心算法:

我们对原数组排序,排完序后的顺序就是最优的选择顺序(从下到上)

排序原则:

我们设交换i和j两头牛的位置,i前面的牛的总重为W

交换前:

第i头牛的压扁指数 W - si

第j头牛的压扁指数 W + wi - sj

则两头牛最大的压扁指数 k1 = max(W - si,W + wi - sj)

同理交换后最大的压扁指数k2 = max(W - sj,W + wj - si)

如果要满足i在j前面,则需满足k1 < k2,反之i在后面

实操代码

cpp 复制代码
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 5e4 + 10;
int n;

struct node
{
int w, s;
}a[N];

bool cmp(node& i, node& j)
{
return i.w + i.s < j.w + j.s;
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) 
        cin >> a[i].w >> a[i].s;
    sort(a + 1, a + 1 + n, cmp);
    LL ret = -1e9 - 10, w = 0;
    for(int i = 1; i <= n; i++)
    {
        ret = max(ret, w - a[i].s);
        w += a[i].w;
    }
    cout << ret << endl;
    return 0;
}
相关推荐
rannn_1115 小时前
【力扣hot100】链表专题|160、206、234、141、142
java·算法·leetcode·链表·面试·开发
数模竞赛Paid answer5 小时前
2026年华东杯数学建模B题医药物流安排问题解题全过程文档及程序
算法·数学建模·数据分析·华东杯
不会代码的小猴6 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
AI备案指南-满满7 小时前
大模型与算法备案全流程详解:从零到通过的完整指南
人工智能·算法·备案·大模型备案·算法备案
江畔柳前堤7 小时前
LLM 训练核心机制深度解析:Warmup、Cosine Decay 与 Perplexity 的完整知识体系
网络·人工智能·深度学习·算法·机器学习·语音识别
一只旭宝7 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
良木林7 小时前
子串 - LeetCode hot 100
算法·leetcode·职场和发展
陌诺曦.8 小时前
Python扩展小练习
算法
coder!mq9 小时前
说几个常见的语法糖?
java·开发语言·算法