题目:HDOJ-1789
题目描述:Ignatius的老师布置了一些作业,每项作业都有deadline和未完成扣的分数,一天只能选择做完一项作业,求Ignatius 被扣的最少的分。
思路:根据贪心策略,先按扣的分从大到小排序,优先完成分数最大的,对每一项作业最好能在deadline当天完成(得以空出更 多的天数),若当天已被占用,则提前一天,以此类推。
ps.这里采用了一个bool数组来标记当天是否被占用(下标对应从第1天到最大deadline),其实用stl的map映射更好些。
以下AC代码
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct hw
{int dl;int rs;
};
bool cmp(hw a, hw b)
{if (a.rs != b.rs)return a.rs > b.rs;elsereturn a.dl > a.dl;
}
int main()
{int T, N, i, sum, maxdl, j;hw a[1001];bool b[10000000];scanf("%d", &T);while (T--){scanf("%d", &N);maxdl = 0;sum = 0;for (i = 0; i < N; i++){scanf("%d", &a[i].dl);if (a[i].dl > maxdl)maxdl = a[i].dl;}for (i = 0; i < N; i++){scanf("%d", &a[i].rs);sum += a[i].rs; //先把扣的分全加上}sort(a, a + N, cmp);memset(b, 0, maxdl + 1);for (i = 0; i < N; i++){for (j = a[i].dl; j >= 1; j--) //从该deadline往回推{if (b[j] == 0) //当第j天未被占用{b[j] = 1;sum -= a[i].rs; //从扣的分里面减去break;}}}printf("%d\n", sum);}return 0;
}