小q打算穿越怪獸谷,他不會打怪,但是他有錢。他知道,只要給怪獸一定的金幣,怪獸就會一直護送他出谷。
在谷中,他會一次遇見n只怪獸,每只怪獸都有自己的武力值和要「賄賂」它所需的金幣。如果小q沒有「賄賂」它而它的武力值又高於護送小q的所有怪獸的武力值之和,這只怪獸就會攻擊小q
小q想知道,要想成功穿越怪獸谷而不被攻擊,最少要準備多少金幣?
輸入描述:
第一行:輸入乙個整數n,代表怪獸的數量
第二行:輸入n個整數:d1、d2、....dn,代表對應怪獸的武力值
第三行:輸入n個整數:p1、p2、.....pn,代表收買對應怪獸所需要的金幣
(1≤n
≤50
1\leq n \leq50
1≤n≤50
、1 ≤d
1,d2
,...
.dn≤
10
121\leq d_1,d_2,....d_n\leq 10^
1≤d1,
d2,
....
dn≤
1012
、1 ≤p
1,p2
,...
.pn≤
21\leq p_1,p_2,....p_n\leq 2
1≤p1,
p2,
....
pn≤
2)輸出描述:
乙個整數,表示所需要的最小金幣數量
因為怪獸是否攻擊你,取決於你所擁有的的怪獸武力值的總和,因此我們應該注重每只怪獸的價效比:
例如:乙隻怪獸的武力值為20,需要1金幣,另乙隻武力值為30,需要2金幣,明顯第一只的價效比要高一些
因為第一只怪獸,花1金幣就能買到20武力值,而第二隻怪獸,花1金幣只能買到15武力值
那麼全買價效比高的有沒有問題呢?
當然有,因為價效比高的不一定都在前面,如果都在後面,那麼之前的錢該出的還是得出
實際上在第二行裡面已經給出每個關卡所需要的最小武力值之和
所以策略應該是:
(1)找出武力值最高的怪獸,並以該武力值作為購買上限,當你所擁有的的武力值之和大於或者等於這個上限時,不必購買
(2)計算每只怪獸的價效比,當你所購買的武力值還沒有到達(1)中的上限時,考慮購買價效比高的怪獸:
但是這一步實際上也有點問題:
你需要考慮購買之後,武力值是否超過了上限,實際情況還會更加複雜
那麼我們換個角度來看待這個問題,之前我們的想法是根據常識來設計一些複雜的演算法,以解決這個問題。
實際上n=50,如果嘗試使用暴力解法,按照排列組合來看,時間複雜度最高也不過是o(2
50)
o(2^)
o(250)
,如果我們能夠在其中加入一些條件,還可以大幅降低這個數值
說起暴力解法,最適合的應該是回溯法了,每次遇到怪獸,我們有兩種選擇:
(1)收買
(2)不收買(有的關卡必須收買,沒得選,比如:第一只怪獸)
我們可以設定乙個武力值上限 和 最小金幣來作為篩選最終結果的條件
class solution
// 初值:假設每個怪獸都要收買
int min_money = sum;
recall(force_value, need_money, current_pos, current_force, current_money, min_money, max_force);
return min_money;
} void recall(vector& force_value, vector& need_money, int current_pos, int current_force, int current_money, int& min_money, int& max_force)
// 開始闖關
int k = 0;
for (int i = current_pos; i < force_value.size(); i++)
else
} }};
騰訊機試題2
題目描述 小q在進行乙個對數字進行拆分的遊戲,遊戲規則如下 小q最初只有乙個整數n,接下來每一輪中,小q被允許對現有的每個數進行下面兩個操作之一 但是拆分操作只允許使用至多k次,現在小q想知道把n完全消去需要多少輪操作。輸入描述 輸入一行包含兩個整數n,k 1 n 100,0 k 100 輸出描述 ...
拼湊硬幣 騰訊機試題
時間限制 每個case 2s 空間限制 128mb 小q十分富有,擁有非常多的硬幣,小q擁有的硬幣是有規律的,對於所有的非負整數k,小q恰好各有兩個面值為2 k的硬幣,所以小q擁有的硬幣就是1,1,2,2,4,4,8,8,小q有一天去商店購買東西需要支付n元錢,小q想知道有多少種方案從他擁有的硬幣中...
騰訊筆試題(1)
const的含義及實現機制,比如 const int i,是怎麼做到i只可讀的?const用來說明所定義的變數是唯讀的。這些在編譯期間完成,編譯器可能使用常數直接替換掉對此變數的引用。初探編譯器static const之實現原理 到商店裡買200的商品返還100優惠券 可以在本商店代替現金 請問實際...