1. 程式人生 > >Doing homework again

Doing homework again

題意:

有 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;
}