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

💡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;
}
相关推荐
罗湖老棍子2 小时前
【例 1】Sightseeing Trip(信息学奥赛一本通- P1494)(洛谷-P10927)
数据结构·算法·图论·最短路·floyd·最小环
stsdddd4 小时前
YOLO算法建筑工地安全帽目标检测数据集16881张:标注核对笔记
算法·yolo·目标检测
CV爱数码5 小时前
论文精读|Learned Primal-Dual:把原始–对偶算法展开成网络
图像处理·算法·计算机视觉·ct·重建·断层扫描
yuniko-n5 小时前
【算法】约瑟夫环问题
java·算法
l1t6 小时前
测试DuckDB v2.1.0-alpha49002的bignum乘法
数据库·sql·算法·duckdb
Nil2086 小时前
LeetCode 283移动零
数据结构·算法·leetcode
CQU_JIAKE6 小时前
10.18【A】
算法
LMT流氓兔6 小时前
第五单元——第4课:给工具参数加校验
java·前端·算法·ai·langchain
物联网软硬件开发-轨物科技7 小时前
【轨物方案】深度解读开关柜智能感知及一键顺控专家系统
大数据·运维·网络·人工智能·算法·机器人
行者全栈架构师8 小时前
我用 TRAE Work 把桌游之夜搬进了浏览器:一个计分器的从创意到上线
前端·算法·架构