51nod 1670 打怪獸 遞推

2021-07-29 06:15:35 字數 1201 閱讀 6947

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)。

接下來一行n個數ai表示怪獸的能量(0<=ai< n)。

output

一行表示答案

input示例

2 0 1

output示例

網上找的題解:

本題的關鍵點是發現如果我能在第i輪打敗怪物j,那麼我一定能在第i+1輪打敗怪物j(前提是我還活著)。

因此我們可以通過遞推來做這題。

令dp[i]表示第i輪我仍然存活時的方案綜述,這裡lyk的能量也必然為i。

顯然dp[0]=n!。因為不管怎麼排列,第0輪總是能存活的。

找到那些可以打敗的怪物數量x,其中這些怪物已經被打敗i個。

此時第i+1輪我仍然能存活的概率為(x-i)/(n-i),只要將這個概率乘上dp[i]就能知道dp[i+1]的值。

#include

using namespace std;

typedef long

long ll;

const int

mod=1000000007;

ll num[100005], dp[100005];

ll pow_mod(ll m)

return ans;

}int main()

ll ans = 0;

for(int i = 2; i <= n; i++)

(ans += dp[n] * n % mod) %= mod;

printf("%lld\n", ans);

return

0;}

51NOD 1670 打怪獸(排列組合)

1670 打怪獸 點我跳轉 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 lyk在玩乙個叫做 打怪獸 的遊戲。遊戲的規則是這樣的。lyk一開始會有乙個初始的能量值。每次遇到乙個怪獸,若lyk的能量值 怪獸的能量值,那麼怪獸將會被打敗,lyk的能量值增加1,否則l...

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號節點,他想要...