智力大冲浪

Problem description

小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。先不要太高兴!因为这些钱还不一定都是你的?!接下来主持人宣布了比赛规则:
  首先,比赛时间分为n个时段(n≤500),它又给出了很多小游戏,每个小游戏都必须在规定期限ti前完成(1≤ti≤n)。如果一个游戏没能在规定期限前完成,则要从奖励费m元中扣去一部分钱wi,wi为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱!

Input format 

共4行。
  第1行为m,表示一开始奖励给每位参赛者的钱;
  第2行为n,表示有n个小游戏;
  第3行有n个数,分别表示游戏1到n的规定完成期限;
  第4行有n个数,分别表示游戏1到n不能在规定期限前完成的扣款数。

Output format

仅1行。表示小伟能赢取最多的钱。

Algorithm design

贪心算法

Problem analysis

不难想到尽量把每一个活动都放在结束前一秒完成,为其他活动争取更大的空间

这只是一个理想的情况,有些活动不得不放弃,所以要优先完成扣款多的游戏

既然如此,把扣款多的游戏从多到少都尽量放在结束前1秒,把玩游戏的时间标记,如果这个时间已经被占用,就往前移,直到无法放置,这个贪心法则绝对是正确的,因为每个游戏最多占用1秒,一旦会导致后面某些游戏玩不了,那么即使不玩这个游戏,后面的游戏也最多只能玩1个,且扣更多的款

 

得证贪心法则:按游戏扣款从多到少按时间从后往前完成

Source code

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int m,n,f[501];
 6 pair <int,int > game[501];
 7 
 8 int main()
 9 {
10     freopen("test.in","r",stdin);
11     freopen("test.out","w",stdout);
12     cin>>m>>n;
13     for(int i=1;i<=n;i++)
14         cin>>game[i].second;
15     for(int i=1;i<=n;i++)
16         cin>>game[i].first;
17     sort(game+1,game+n+1);
18     for(int i=n;i>=1;i--)
19     {
20         int sub=game[i].second-1;
21         while(f[sub]&&sub)sub--;
22         if(f[sub])
23         {
24             m-=game[i].first;
25             continue;
26         }
27         f[sub]=1;
28     }
29     cout<<m<<endl;
30     return 0;
31 }
View Code

 

posted @ 2018-07-14 15:11  Srzer  阅读(613)  评论(0编辑  收藏  举报