貪心-Doing Homework again HDU - 1789
阿新 • • 發佈:2021-11-19
題目
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; }