菜鸟haqima的第一天(c++)篇

贪心算法(greedy algorithm)

想要学习更多,可以去我的github上,目前更了23种其他算法,已经公开当然后续也会在csdn上写更多
从英文名称不难看出,很有可能用到库函数algorithm。不妨写上!!由于博主目前只会c++(今后会努力的!!!),也就是include algorithm头函数中
那贪心算法究竟是干什么呢?
贪心算法
别名:贪婪法
用途:寻找最优解问题的常用方法
思路: 1.将求解过程分成若干个步骤
2.每个步骤选取当前状态下最好/最优的选择(局部最优解)
3.最后将步骤堆叠出结果—显然是最好/最优的解。
基本步骤:1.将原问题分解为子问题
2.找出贪心策略
3.得到每一个子问题的最优解
4.将所有局部最优解的集合构成称为原问题的一个解
废话不多说(实际说了挺多)上手一道题方便理解

小明的比赛

题目描述
小明的算法竞赛水平很高,他经常参加网上的比赛。

比赛的规则是这样的:要在规定时间内解决 n 道题,解决时间越晚失去的 分数就越多。

当然如果有错误提交还会扣额外的分数。为了简化题目,我们假设小明所有 题目都可以一遍 AC。

小明实在是太强了,以致于他看完所有题目就都会做了。

剩下的就是把它们 写出来的问题。

小明掐指一算,算出了写每道题需要的时间 Ti,以及每道题每分 钟会失去的分数 Ai

也就是说,如果他在 x 分钟时完成这道题,他将失去 x * Ai 的分数。 请合理安排做题顺序,使得当小明做完比赛时,失去的分数尽可能少

输入
第一行给出一个正整数 T(T<=10),表示数据组数。

对于每组数据,第一行一个正整数 n,表示这场比赛的题目数。第二行 n 个 整数,表示做每道题需要的时间 Ti。

第三行 n 个整数,表示每题每分钟失去的分 数 Ai。 其中:0<n<=100000,0<Ti,Ai<=10000

输出
对于每组数据,输出一个整数,表示最少失去的分数。
样例输入 复制
1
3
10 10 20
1 2 3
样例输出 复制
150

博主读完三遍后依然很懵逼,而且头脑一热,不就是10* 1+10* 2+20* 3==90吗?
明显不对
自己在草稿纸上写了一遍才恍然大悟
在这里插入图片描述
奉上代码

#include <iostream>
#include <algorithm>
using namespace std;
struct AA
{
    long long ti1;
    long long ai;
    double ti2;//每扣1分所用的时间
}x[100000];
int compare(AA x, AA y)
{
    return x.ti2 < y.ti2;
}
 
int main()
{
    long long t;
    long long n;
    long long answer = 0, timsum = 0;
    cin >> t;
    while (t--)
    {
        cin >> n;
        for (int i = 0;i < n;i++)
            cin >> x[i].ti1;
        for (int i = 0;i < n;i++)
        {
            cin >> x[i].ai;
            x[i].ti2 = double(x[i].ti1) / x[i].ai;//算出每一组(每扣1分所用的时间)类似于:比较每一道题的价值/权重(是否最优)
        }
 
        sort(x, x + n, compare);//按权重从大到小排列/所扣每1分用的时间从小到大排列(sort效率较高)
 
        for (int i = 0;i < n;i++)
        {
            timsum += x[i].ti1;
            answer += timsum * x[i].ai;//见下方表格
        }
        cout << answer << endl;
        answer = 0, timsum = 0;
 
 
    }
 
timsumanswer
第一次1010*2
第二次10+20(10+20)*3+10 *2
第三次10+20+10(10+20+10)*1+ (10+20)*3+10 *2

注释:按样例输入,权重由大到小:10 *2->20 *3->10 *1
读懂这个对贪心就有大概了解
今天就这么多吧
给未来的自己:
坚持下去,纵使自己得不到别人的鲜花和掌声,收获知识就足以自豪和骄傲了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值