1. 程式人生 > 其它 >智力大沖浪 C++

智力大沖浪 C++

題目描述

小偉報名參加中央電視臺的智力大沖浪節目。本次挑戰賽吸引了眾多參賽者,主持人為了表彰大家的勇氣,先獎勵每個參賽者 m 元。先不要太高興!因為這些錢還不一定都是你的?!接下來主持人宣佈了比賽規則:首先,比賽時間分為 n 個時段 (n≤500),它又給出了很多小遊戲,每個小遊戲都必須在規定期限 ti 前完成 (1≤ti≤n)。如果一個遊戲沒能在規定期限前完成,則要從獎勵費 m 元中扣去一部分錢 wi,wi 為自然數,不同的遊戲扣去的錢是不一樣的。當然,每個遊戲本身都很簡單,保證每個參賽者都能在一個時段內完成,而且都必須從整時段開始。主持人只是想考考每個參賽者如何安排組織自己做遊戲的順序。作為參賽者,小偉很想贏得冠軍,當然更想贏取最多的錢!注意:比賽絕對不會讓參賽者賠錢!

輸入描述

多組輸入,每組共 4 行,

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

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

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

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

輸出描述

多組輸入。對於每組輸入,僅 1 行,表示小偉能贏取最多的錢

樣例輸入

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

樣例輸出

Copy to Clipboard
9950

#include<iostream>
#include<algorithm>
#include
<cstring> using namespace std; const int N=510; int n,m,f[N]; struct node{ int t,w; }a[N]; int cmp(node x,node y) { return x.w>y.w; } void work() { sort(a+1,a+1+n,cmp); for (int i=1;i<=n;i++) { bool pd=false; for (int j=a[i].t;j>=1;j--) {
if (f[j]==0) //可以安排這個遊戲 { f[j]=1; pd=true; break; } } if (pd==false) m-=a[i].w; } } int main() { while(cin>>m>>n){ for (int i=1;i<=N;i++) a[i].t=0; for (int i=1;i<=N;i++) a[i].w=0; memset(f, 0, sizeof(f)); for (int i=1;i<=n;i++) scanf("%d",&a[i].t); for (int i=1;i<=n;i++) scanf("%d",&a[i].w); work(); cout<<m<<endl;} return 0; }

 

思路:

因為不同的小遊戲不能準時完成時具有不同的扣款權數,而且是求問題的最優解,所以很容易想到用貪心演算法求解。

貪心策略是讓扣款數額大的儘量在規定的期限內完成。

這樣我們就先把這些任務按照扣款的數額進行排序,把大的排在前面,進行放置。

假如罰款最多的一個任務的完成期限是k,我們應該把它安排在哪個時段完成呢?應該放在小於等於k的最靠後的時間段。一旦出現一個不可能在規定期限內完成的任務,就直接扣錢

演算法的時間複雜度是O(n^2)




部分轉載自:https://blog.csdn.net/weixin_45485187/article/details/102797674。本處程式碼為過oj有所修改。