HDU 1789 Doing Homework again

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789

题目大意:

Ignatius有N项作业要完成。每项作业都有限期,如果不在限期内完成作业,期末考就会被扣相应的分数。给出测试数据T表示测试数,每个测试以N开始(N为0时结束),接下来一行有N个数据,分别是作业的限期,再有一行也有N个数据,分别是若不完成次作业会在期末时被扣的分数。求出他最佳的作业顺序后被扣的最小的分数。(每个作业费时一天)。

解题思路:

求被扣分数最少。这是一道贪心算法。于是第一个想法就是:使用一个结构体保存每门作业的限制时间date和被扣的分数reduce。

对限制时间排序,时间越靠前的要越先完成,若限制时间一样,则把被扣分数大的排在前面,保证被扣分数大的要先完成。这就保证了完成的作业数做多。但是这样排序后,产生了一个问题,完成的作业数最多,被扣的分数不一定是最小,例如:

输入:7

1 4 6 4 2 4 3(每门作业的限制时间)

3 2 1 7 6 5 4(每门课若不完成期末被扣的分数)

排序后

1 2 3 4 4 4 6

3 6 4 7 5 2 1

如果只按上述排序从头去到尾则结果是7。这是因为在上面的数组中,可以选择完成(4 5),放弃(1 3)。这样才是最小的结果。

所以做法是:设一个mark数组,标记能够完成的。然后对排序后的结构体数据进行for循环,遇到

if(day<date(即现在的时间不超过限制时间)则表示这个作业可以完成,)

{所以day++,同时mark[i]要标记这个作业可以完成。}

else(day>=date,则证明这个作业放在这里做没办法完成的。)

{

考虑在前面标记过的可完成的作业,是否有某个作业的reduce比目前的ruduce小。

if(如果有)

{则证明,可以选择完成当前的这个作业,而不完成前面reduce比当前小的作业,所以两个作业的reduce交换。}

   else(如果没有)

          {则什么都不操作,进入下一次循环}

}


代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
    int date,reduce;
}p[1005];
bool cmp(node a,node b)
{
    if(a.date==b.date) return (a.reduce>b.reduce);
        else return  a.date<b.date;
}
int main()
{
    int t;
    bool mark[1005];
    scanf("%d",&t);
    while(t--)
    {
        int ans=0;
        int day=0;
        memset(mark,false,sizeof(mark));
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&p[i].date);
        for(int i=1;i<=n;i++)
            scanf("%d",&p[i].reduce);
        sort(p+1,p+n+1,cmp);
        for(int i=1;i<=n;i++)
        {

            if(day<p[i].date)
                 {
                     mark[i]=true;
                      day++;
                 }
            else
            {
                for(int j=1;j<i;j++)
                    if(p[j].reduce<p[i].reduce && mark[j]==true)
                {
                    swap(p[i].reduce,p[j].reduce);
                    swap(p[i].date,p[j].date);
                }
            }

        }
        for(int i=1;i<=n;i++)
            if(mark[i]==false)
              ans=ans+p[i].reduce;
            printf("%d\n",ans);




    }
    return 0;
}



内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端离系统,将AOA应用于图像割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像割模块,引入更复杂的预处理或后处理技术以提升割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值