1670 打怪獸
(點我跳轉)
基準時間限制:1 秒 空間限制:131072 kb 分值: 40
難度:4級演算法題
lyk在玩乙個叫做「打怪獸」的遊戲。
遊戲的規則是這樣的。
lyk一開始會有乙個初始的能量值。每次遇到乙個怪獸,若lyk的能量值》=怪獸的能量值,那麼怪獸將會被打敗,lyk的能量值增加1,否則lyk死亡,遊戲結束。
若怪獸全部打完,遊戲也將會結束。
共有n個怪獸,由於lyk比較弱,它一開始只有0點能量值。
n個怪獸排列隨機,也就是說共有n!種可能,lyk想知道結束時它能量值的期望。
由於小數點比較麻煩,所以你只需要輸出期望*n!關於1000000007取模後的值就可以了!
例如有兩個怪獸,能量值分別為,那麼答案為2,因為遊戲結束時有兩種可能,lyk的能量值分別為0和2。期望為1,1*2!=2,所以答案為2。
input
第一行乙個數n(1<=n<=100000)。input示例接下來一行n個數ai表示怪獸的能量(0<=aioutput
一行表示答案
2output示例0 1
2大致思路:臨走時粗略地看了一下題目,半路上才發現沒看資料範圍,而且沒注意怪獸的能量值是0~n-1還是題目給定,就先按照0~n-1想了一下,結果很快就想出來了
又想如果能量值是題目給定該怎麼做,發現這樣不過是前者的加強版,也能運用排列組合輕鬆解決
首先知道期望計算公式為:e=∑p[i]*i; (i表示遊戲結束時能量,p[i]表示遊戲結束時能量為i的概率)
而 p[i]*n! 表示遊戲結束時能量為i的方案數,所以用排列組合計算達到能量為i時的方案數即可
模擬打怪獸的過程,設當前能量為energy,能量達到energy時的方案數為way,不能打過的怪獸共rem只,則還剩餘n-energy只怪獸未打,有兩種情況:
①打乙隻不能打過的怪獸,則遊戲結束,則結束時能量值為energy的方案數共:way*rem*(n-energy-1)!
②打一只能打過的怪獸,則遊戲繼續,能量值達到energy+1時的方案數為way*(n-energy-rem)
最開始想用二分搜尋能量為energy時,能打過怪獸的下標的最大值,這樣時間複雜度為:o(n*logn)
後來又想到可以在o(n)內預處理出能量為energy時,能打過怪獸的下標的最大值,這樣時間複雜度為:o(n)
看了一下排名第一的**,發現根本就不需要預處理,直接計算時就可以算出,時間複雜度仍為:o(n),而且自己還寫複雜了
#include #include #include using namespace std;
const int maxn=100005;
const long long mod=1000000007;
int n,a[maxn],index[maxn],energy,rem;//index[i]表示能量為k時,能打過的怪獸的下標的最大值
long long factorial[maxn];//factorial[i]表示 i!
long long ans,way;//way表示達到當前能量值的方案數
int main()
index[i]=j-1;
}ans=energy=0;
way=1;
while(index[energy]>=energy)
if(energy==n)
else
printf("%i64d\n",ans);
}return 0;
}
51nod 1670 打怪獸 遞推
lyk在玩乙個叫做 打怪獸 的遊戲。遊戲的規則是這樣的。lyk一開始會有乙個初始的能量值。每次遇到乙個怪獸,若lyk的能量值 怪獸的能量值,那麼怪獸將會被打敗,lyk的能量值增加1,否則lyk死亡,遊戲結束。若怪獸全部打完,遊戲也將會結束。共有n個怪獸,由於lyk比較弱,它一開始只有0點能量值。n個...
52nod 1670打怪獸 期望dp
定義dp i dp i dp i 為能量為i ii時可行的方案數 那麼顯然dp 0 n dp 0 n dp 0 n dp i a i 1 i 1 n i 1 dp i a i 1 i 1 n i 1 dp i a i 1 i 1 n i 1 其中i 1i 1 i 1是已經殺死的敵人個數 a i 1 ...
WUST 1627 打怪遊戲(優先佇列 bfs)
time limit 1 sec memory limit 128 mb 64bit io format lld submitted 12 accepted 10 submit status web board 一顆樹有n個節點 編號從0到n 1 樹上每乙個節點可能有多隻怪物。小明在0號節點,他想要...