1. 程式人生 > 其它 >貪心-Doing Homework again HDU - 1789

貪心-Doing Homework again HDU - 1789

題目

https://vjudge.net/problem/HDU-1789

思路一

思路一是,讓價值儘量大的作業,儘量往後安排。

為了實現思路一,我們需要從後往前遍歷”時間”,在每個時間節點選擇滿足當前條件的最大值,其中最大值我們使用優先佇列實現。

以樣例3為例,如圖所示

1
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4    

從右往左看,黃色表示選擇做的作業,灰色表示已經做了,綠色是最後沒做的

程式碼

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;

struct node {
	int time, price;
	friend bool operator < (struct node a, struct node b)
	{
		if (a.price != b.price)	return a.price < b.price;
		else return a.time < b.time;
	}//使用小於號,對於優先佇列,效果是price大的靠近top;對於sort函式,會把price小的排在陣列前面
};

bool cmp(node a, node b) {
	return a.time > b.time;
}

int main(void) {
	int T = 0;
	cin >> T;
	while (T--) {
		priority_queue<node> Q;
		node arr[1005];
		int N, total = 0, ddl = 0;
		cin >> N;
		
		for (int i = 0; i < N; i++) {
			cin >> arr[i].time;
			ddl = ddl > arr[i].time ? ddl : arr[i].time;
		}
		for (int i = 0; i < N; i++) {
			cin >> arr[i].price;
			total += arr[i].price;
		}
		
		sort(arr, arr + N, cmp);
		int j = 0;
		for (int i = ddl; i >= 1; i--) {//錯誤:i >= 0
			for (; arr[j].time >= i && j < N; j++) {//錯誤:1. time >= ddl 2. 缺少&& j < N
			//	printf("%d has been push\n", arr[j].time);
				Q.push(arr[j]);
			}
			if (!Q.empty()) {
			//	printf("total is %d, Qtop is %d\n", total, Q.top().price);
				total -= Q.top().price;
				Q.pop();
			}
		}
		cout << total << endl;
	}
	
	return 0;
}

思路二

思路二的核心其實和思路一一樣——讓價值儘量大的作業,儘量往後安排。但是實現的方法不一樣,既然我們想要讓價值大的往後排,那我們不是隻要讓它在最後一天完成就好了?但這樣可能會有重複,沒關係,那就讓它往前一天,還是不行就兩天,以此類推。為此我們需要將價值從大到小排序。

還是以樣例3為例子,價值從大到小,如圖所示

1
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4    

程式碼

#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;

struct node {
	int time, price;
};

bool cmp(node a, node b) {
	return a.price > b.price;
}

int main(void) {
	int T = 0;
	cin >> T;
	while (T--) {
		priority_queue<node> Q;
		node arr[1005];
		int vis[1005];
		memset(vis, 0, sizeof(vis));
		int N, total = 0, spend = 0, ddl = 0;
		cin >> N;
		
		for (int i = 0; i < N; i++) {
			cin >> arr[i].time;
			ddl = ddl > arr[i].time ? ddl : arr[i].time;
		}
		for (int i = 0; i < N; i++) {
			cin >> arr[i].price;
			total += arr[i].price;
		}
		
		sort(arr, arr + N, cmp);
		for (int i = 0; i < N; i++) {
		//	for (int k = 1; k <= ddl; k++)	printf("%d ", vis[k]);	cout << endl;
			int j;
			for (j = arr[i].time; j >= 1 && vis[j] != 0; j--){}//這裡很多i啊j啊,一定要沉下心來理清邏輯
			vis[j] = arr[i].price;
		}
		//for (int k = 1; k <= ddl; k++)	printf("%d ", vis[k]);	cout << endl;
		for (int i = 1; i <= ddl; i++) spend += vis[i];
		cout << total - spend << endl;
	}
	return 0;
}

參考部落格

  1. https://www.cnblogs.com/blumia/p/hdu1789.html
  2. https://blog.csdn.net/liluoyu_1016/article/details/78938559