Doing homework again
阿新 • • 發佈:2018-12-09
題意:
有 n 門作業,每門作業都有自己的截止期限,當超過截止期限還沒有完成作業,就會扣掉相應的分數。問如何才能使扣分最少。
解題思路1:
把 n 門作業按分數從大到小排序,然後每次都把作業安排在離它的截止期限最近的一天(先安排在截止日期當天,如當天已有安排,則往前一天找),並把此天標記為已用,若不能安排,則扣分。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; bool vis[1000]; #define fre freopen("C:\\Users\\Dell\\Desktop\\in.txt", "r", stdin); struct node{ int dead; int sub; bool operator < (const node &a)const{ return a.sub<sub; } }stu[1005]; int main(){ //fre; int t, n, totsub; cin >> t; while (t--){ vis[0] = 1; totsub = 0; cin >> n; for (int i = 0; i<n; i++)cin >> stu[i].dead; for (int i = 0; i<n; i++)cin >> stu[i].sub, totsub += stu[i].sub; sort(stu, stu + n); for (int i = 0; i<n; i++){ //int k = 0; for (int j = stu[i].dead; j >= 1; j--){ if (vis[j] == 0){ vis[j] = 1; totsub -= stu[i].sub; break; } } } cout << totsub << endl; memset(vis, 0,sizeof(vis) ); } return 0; }
解題思路2:
先對日期從小到大排序,如果日期相同,則扣分多的排在前面。如果相同日期內有扣分多的,則就用前面做扣分少的作業的時間來做這門作業;如果沒有比他小的,就扣這門作業的分。On,大大優於前面的演算法。
#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<memory.h> #include<queue> #include <bits\stdc++.h> using namespace std; #define fre freopen("C:\\Users\\Dell\\Desktop\\in.txt", "r", stdin); priority_queue<int, vector<int>, greater<int> >q; //小的先出佇列 struct in { int d, s;//deadline,score }c[1010]; bool cmp(in a, in b){ return a.d<b.d; } int main() { fre; int T, n, i, j, t, cnt, ans; scanf("%d", &T); while (T--){ cnt = ans = 0; t = 0; while (!q.empty()) q.pop(); scanf("%d", &n); for (i = 1; i <= n; i++) scanf("%d", &c[i].d); for (i = 1; i <= n; i++) scanf("%d", &c[i].s); sort(c + 1, c + n + 1, cmp); for (i = 1; i <= n; i++){ q.push(c[i].s); if (c[i].d>t) t++; //如果截止日期相同,也即某一天有不止一門課要交,則一定要 else { //從中選擇一門放棄,選代價最小的,但是並未決定當天要做哪門 ans += q.top(); q.pop(); } } printf("%d\n", ans); } return 0; }