【练习12】 贪心算法 1004 Doing Homework again

本文介绍了一种使用贪心算法解决作业安排问题的方法,通过优先选择具有最大惩罚值的作业,确保作业截止日期与分配日期之间的合理匹配,从而最小化未分配作业的总惩罚值。

算法思路:贪心。

先对所有的homework排序,deadline大的在后面,然后依次从后往前分配每一天的任务,因为分配给某一天的homework的deadline一定要大于等于这一天的下标(下标依次为1,2,3,...,N),所以遍历所有可行的(deadline>当前要分配的这一天的下标)homework选择penalty最大的哪一个就行了,但是选择之后要记得进行标记,下次遍历的时候就不要再选了。最后再根据标记统计一下没有分配的homework的总的penalty就是结果了。

代码如下,水平有限,写得有点挫,如果要学习代码还是参考其他的大牛,不过上面介绍的思路是没错的:

//模板开始
#include <string>   
#include <vector>   
#include <algorithm>   
#include <iostream>   
#include <sstream>   
#include <fstream>   
#include <map>   
#include <set>   
#include <cstdio>   
#include <cmath>   
#include <cstdlib>   
#include <ctime>
#include <iomanip>
#include <queue>
#include <string.h>
#define SZ(x) (int(x.size()))
using namespace std;

int toInt(string s){
	istringstream sin(s); 
	int t; 
	sin>>t; 
	return t;
}
template<class T> string toString(T x){
	ostringstream sout; 
	sout<<x; 
	return sout.str();
}
typedef long long int64;
int64 toInt64(string s){
	istringstream sin(s); 
	int64 t; 
	sin>>t;
	return t;
}
template<class T> T gcd(T a, T b){ 
	if(a<0) 
		return gcd(-a, b);
	if(b<0) 
		return gcd(a, -b);
	return (b == 0)? a : gcd(b, a % b);
}

#define LOCAL
//模板结束(通用部分)

struct Work
{
	int penalty;
	int deadline;
	int selected;
	friend bool operator<(Work w1, Work w2)
	{
		if(w1.deadline == w2.deadline)
		{
			return w1.penalty > w2.penalty;
		}
		else
		{
			return w1.deadline < w2.deadline;
		}
	}
};

#define MAXN 1005
Work d[MAXN];
int ind[MAXN];
int sz;
int exits[MAXN];

int main()
{
#ifdef LOCAL
	//freopen("shuju.txt", "r", stdin);
#endif

	int cas;
	int N;
	cin>>cas;
	for(int cc = 0; cc < cas; cc++)
	{
		cin>>N;
		for(int i = 0; i < N; i++)
		{
			cin>>d[i].deadline;
		}
		for(int i = 0; i < N; i++)
		{
			cin>>d[i].penalty;
		}
		for(int i = 0; i < N; i++)		//初始化
		{
			d[i].selected = 0;
		}
		sort(d, d + N);
		sz = 0;
		memset(exits, 0, sizeof(exits));
		memset(ind, 0, sizeof(ind));
		for(int i = 0; i < N; i++)
		{
			int temp = d[i].deadline;
			if(!exits[temp])
			{
				ind[temp] = i;
				sz = max(sz, temp);
				exits[temp] = 1;
			}
		}
		for(int i = sz; i >= 1; i--)
		{
			int j = i;
			while (!exits[j] && j <= sz)
			{
				j++;
			}
			if(j > sz)
			{
				continue;
			}
			int k = ind[j];
			int xiabiao = k;
			int m = 0;
			for(int kk = k; kk < N; kk++)
			{
				if(!d[kk].selected && m < d[kk].penalty)
				{
					m = d[kk].penalty;
					xiabiao = kk;
				}
			}
			if(m != 0)
			{
				d[xiabiao].selected = 1;
			}
		}
		int ans = 0;
		for(int i = 0; i < N; i++)
		{
			if(!d[i].selected)
			{
				ans += d[i].penalty;
			}
		}
		cout<<ans<<endl;
	}

	return 0;
}







评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值