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

💡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;
}
相关推荐
金融RPA机器人丨实在智能6 小时前
2026动态规划新风向:实在智能Agent如何以自适应逻辑重构企业效率?
算法·ai·重构·动态规划
elseif1236 小时前
【C++】并查集&家谱树
开发语言·数据结构·c++·算法·图论
偷吃的耗子6 小时前
【CNN算法理解】:卷积神经网络 (CNN) 数值计算与传播机制
人工智能·算法·cnn
徐小夕@趣谈前端6 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
问好眼7 小时前
【信息学奥赛一本通】1275:【例9.19】乘积最大
c++·算法·动态规划·信息学奥赛
Daydream.V7 小时前
逻辑回归实例问题解决(LogisticRegression)
算法·机器学习·逻辑回归
代码无bug抓狂人7 小时前
C语言之表达式括号匹配
c语言·开发语言·算法
不穿格子的程序员7 小时前
从零开始写算法——普通数组篇:缺失的第一个正数
算法·leetcode·哈希算法
Nebula_g7 小时前
线程进阶: 无人机自动防空平台开发教程(更新)
java·开发语言·数据结构·学习·算法·无人机
rit84324997 小时前
基于MATLAB的环境障碍模型构建与蚁群算法路径规划实现
开发语言·算法·matlab