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

💡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;
}
相关推荐
147API5 分钟前
如何设计“回答、追问、停答”三类蒸馏训练集
人工智能·算法·机器学习
朝朝辞暮i20 分钟前
C++ 第7课 while 循环
开发语言·c++·算法
blxr_1 小时前
力扣hot100爬楼梯https://leetcode.cn/problems/climbing-stairs/
算法·leetcode·职场和发展
pride.li1 小时前
ISP标定-NR标定(Noise Reduction,降噪校准)
算法·计算机视觉·isp
CQU_JIAKE1 小时前
9.29【A】
算法·深度优先
没落之王2 小时前
AI在文言文——论文脉复苏对AI的意义
大数据·人工智能·算法
u0111026752 小时前
工具页案例图如何编写 alt让图片说明与处理场景对应
java·前端·javascript·图像处理·人工智能·算法·ai作画
阿狗童鞋2 小时前
数据结构与算法实战指南
数据结构·算法
Navigator_Z3 小时前
LeetCode //C - 1275. Find Winner on a Tic Tac Toe Game
c语言·算法·leetcode
未来之窗软件服务3 小时前
递归时间复杂度演算T (n)=aT (n/b)+f (n)-东方仙盟
算法·仙盟创梦ide·东方仙盟