题目:
有n个作业,每个作业正好一天做完。每个作业都有一个截止日期,如果在deadline之前完不成,就要扣掉相应的学分。
求解,最少扣掉多少学分
分析:
这是一道比较简单的贪心,求最少要扣多少学分,那么就要按照学分排序。但是有一个截止日期的限制,所以每个作业要在截止日期前完成才有效
那么就是先按照学分排序,如果分数相同deadline时间后的优先完成(这样可以将前面的留出来,以便后面的比较高的学分有比较靠前的deadline可以有得选择,保证结果最佳)
然后用一个bool的数组,表示每个日期是否被使用,每次要判断一个作业是否可做,就要先判断在这个作业的deadline之前有没有空闲时间去做
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T;
struct node {
int sc, ti;
}no[1050];
int n;
bool vis[1050];
bool cmp( node a, node b ) {
if ( a.sc == b.sc ) return a.ti > b.ti;
return a.sc > b.sc;
}
bool cando( int x ) {
for ( int i = no[x].ti; i > 0; --i ) if ( !vis[i] ) {
vis[i] = true;
return true;
}
return false;
}
int main()
{
while ( scanf("%d", &T) != EOF ) {
while ( T-- ) {
scanf("%d", &n);
int day = 0, gra = 0;
for ( int i = 0; i < n; ++i ) {
scanf("%d", &no[i].ti);
day = max( day, no[i].ti);
}
for ( int i = 0; i < n; ++i ) {
scanf("%d", &no[i].sc);
gra += no[i].sc;
}
sort( no, no+n, cmp );
memset( vis, 0, sizeof(vis) );
for ( int i = 0; i < n && day > 0 ; ++i ) {
//printf("%d %d\n", tmp = cando(i), no[i].ti);
if ( cando(i) ) day--, gra -= no[i].sc;
}
printf("%d\n", gra);
}
}
}