1. 程式人生 > >LOJ#10004 智力大沖浪

LOJ#10004 智力大沖浪

題目連結

題目描述

小偉報名參加中央電視臺的智力大沖浪節目。本次挑戰賽吸引了眾多參賽者,主持人為了表彰大家的勇氣,先獎勵每個參賽者 m 元。先不要太高興!因為這些錢還不一定都是你的?!接下來主持人宣佈了比賽規則:

首先,比賽時間分為 n 個時段,它又給出了很多小遊戲,每個小遊戲都必須在規定期限 ti 前完成。如果一個遊戲沒能在規定期限前完成,則要從獎勵費 m 元中扣去一部分錢 wi​ 為自然數,不同的遊戲扣去的錢是不一樣的。當然,每個遊戲本身都很簡單,保證每個參賽者都能在一個時段內完成,而且都必須從整時段開始。主持人只是想考考每個參賽者如何安排組織自己做遊戲的順序。作為參賽者,小偉很想贏得冠軍,當然更想贏取最多的錢!注意:比賽絕對不會讓參賽者賠錢!

輸入格式

輸入共四行。

第一行為 m,表示一開始獎勵給每位參賽者的錢;

第二行為 n,表示有 n 個小遊戲;

第三行有 n 個數,分別表示遊戲 1 到 n 的規定完成期限;

第四行有 n 個數,分別表示遊戲 1 到 n 不能在規定期限前完成的扣款數。

輸出格式

輸出僅一行,表示小偉能贏取最多的錢。

樣例

樣例輸入

10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10

樣例輸出

9950

資料範圍與提示

對於 100% 的資料,有 n≤500,1≤ti≤n。

要贏取最多的錢應該使扣款數最少,因此應先完成扣款數多的遊戲。

貪心策略:先將遊戲按扣款數w從大到小排序,安排遊戲i在ti之內儘量靠後的時間段

,若ti時間內排滿,則放棄該遊戲。

AC程式碼:  

#include<iostream>
#include<sstream>
#include<algorithm>
#include<string>
#include<cstring>
#include<iomanip>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<map>
#define mem(a,b) memset(a,b,sizeof(a))
#define e 2.71828182
#define Pi 3.141592654
using namespace std;
int main()
{
	int m,n,t[501],w[501];
	cin>>m>>n;
	for(int i=1;i<=n;i++) cin>>t[i];
	for(int i=1;i<=n;i++) cin>>w[i];
	
	for(int i=1;i<=n;i++)//將遊戲按扣款數w從大到小排序
	for(int j=i+1;j<=n;j++)
	if(w[i]<w[j]) swap(t[i],t[j]),swap(w[i],w[j]);
	
	int book[501],ans=m;
	mem(book,0);
	for(int i=1;i<=n;i++)
	{
		bool flag=false;//是否能在期限內完成該遊戲
		for(int j=t[i];j>=1;j--)
		if(!book[j]) 
		{
			book[j]=1,flag=true;
			break;
		}
		
		if(!flag)
		{
			for(int j=n;j>=1;j--)
			if(!book[j]) 
			{
				book[j]=1;
				break;
			}
			ans-=w[i];
		} 
	} 
	cout<<ans;
}