博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
杭电ACM——1789,Doing Homework Again(贪心)
阅读量:4049 次
发布时间:2019-05-25

本文共 1332 字,大约阅读时间需要 4 分钟。

题意:有N个作业,每个作业都有一个t[i],s[i]分别表示ddl和超过ddl会扣除的分数,每天固定完成一个作业,求最合理的安排,使得被扣除的分数最少。输入T,表T个样例,每个样例首行为N,第二行为t[N],第三行为s[N]。

原题链接:

分析:

一开始直觉是按ddl从小到大排序,然后依次完成每个作业,但并没有这么简单,卡在了题中第三个样例。正确的做法应该是:
1.将t[i]从小到大排序,t[i]相同则按s[i]从大到小排;
2.设time为写作业的第几天,当time<=t[i]时,说明能在ddl前完成,time++。而当time>t[i]时,说明超过了ddl了,此时,应该遍历s[0]~s[i-1],若发现有s[k]<s[i]的,说明牺牲掉第k项作业来完成第i项作业,扣除的分数更少,这样安排更值得,否则,则直接弃掉作业i;
3.特别注意,超过ddl的数据要进行处理,否则可能会在后面的遍历操作中成了搅屎棍。
时间复杂度较大,但题中的数据较小,1<=N<=1000,解起来还是绰绰有余的。

伪代码如下:

输入T
while(T- -)
{
int time,flag;
long long min,score;
输出N;
输入t[N],s[N];
排序;
for(i=0;i<=n-1;i++)
{
if(time<=t[i]) time++;
else
{
min=s[i];flag=i;
for(j=0;j<i;j++)
{
if(min>s[j]){
min=s[j];flag=j;}
}
score+=min;
s[flag]=inf; //注意!!!这一步很重要,将s[i]设为inf,表示已经超过ddl了
}
输出score;
}

代码入下:

#include
#define inf 100000000using namespace std;long long t[1005],s[1005];void sort(int n){ int i,j,k; for(i=0;i<=n-2;i++) { k=i; for(j=i+1;j<=n-1;j++) if(t[k]>t[j]) k=j; else if(t[k]==t[j]) { if(s[k]
s[j]) { min=s[j]; flag=j; } } if(min!=s[i]) { score+=min; s[flag]=inf; } else { score+=min; s[i]=inf; } } } printf("%lld\n",score); } return 0;}

Tips:其实解答过程中出现了一些困扰,担心会出现这样或那样的情况(具体忘了)而导致算法错误,但是,事实上不必过分的担忧的,因为到最后证明了出来,这些情况是不可能出现的。所以,如果下次再出现类似的担忧,不必慌,尝试证明这些搅屎棍是不可能出现的,成功了就继续,失败了就重来。

转载地址:http://dfdci.baihongyu.com/

你可能感兴趣的文章
模拟屏学习资料_什么是PAL制式
查看>>
模拟屏学习资料_模拟视频 入门
查看>>
西藏之旅
查看>>
Oracle中定时执行问题
查看>>
三时业
查看>>
佛教三宝-三皈依
查看>>
杂阿含经喻世间有四等马
查看>>
考研前夜涂笔
查看>>
英语复试自我介绍
查看>>
什么是熵?
查看>>
拼凑、摘抄-评李代平的软件工程第二版
查看>>
误传了数千年的几个名句
查看>>
韩复榘经典语录
查看>>
厅、部、局、司区分大小
查看>>
VS2005中使用C#编写MDI窗口根据子窗口个数控制菜单项的enabled属性
查看>>
北川邓家“刘汉小学”无一死亡奇迹背后的真相
查看>>
救灾,从来没有胜利
查看>>
.net 2.0中ConfigurationManager替代了原来的ConfigurationSettings
查看>>
Asp.net 2.0中使用Datawindow.net2.0
查看>>
常用命名法:骆驼命名法,匈牙利命名法和帕斯卡命名法
查看>>