1. 程式人生 > >HDOJ-1789 Doing Homework again(貪心演算法)

HDOJ-1789 Doing Homework again(貪心演算法)

題目描述: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;
	else
		return 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;
}