Codeforces 722E 組合數學 DP

2022-06-28 04:30:13 字數 1280 閱讀 6867

題意:有乙個n * m的棋盤,你初始在點(1, 1),你需要去點(n, m)。你初始有s分,在這個棋盤上有k個點,經過一次這個點分數就會變為s / 2(向上取整),問從起點到終點的分數的數學期望是多少?

思路:按照套路,先把這k個點按照pair的方式進行排序,設dp[i][j]為從起點到點i之前經過了至少j個減分點,到點i的數學期望。那麼所有在它之前的可以向它轉移的點向它轉移。那麼dp[i][j] = σ(dp[u][j - 1] - dp[u][j]) * g(u, i)。其中g(u, i)是u, i之間沒有限制條件的走法數目,用組合數學的方法計算即可。這樣相當於是前面恰好走過j個點 + 可能走過大於乙個點的方式轉移過來,這樣可以保證計數的不重不漏。

**:

#include #define inf 0x3f3f3f3f

#define db double

#define ll long long

#define pii pairusing namespace std;

const int maxn = 200010;

const ll mod = 1e9 + 7;

ll dp[2010][40];

pii a[2010];

ll v[maxn], inv[maxn];

ll qpow(ll x, ll y)

return ans;

}void init(int n)

inv[n] = qpow(v[n], mod - 2);

for (int i = n - 1; i >= 0; i--)

}ll c(ll n, ll m)

ll cal(int x, int y)

ll b[50];

int main()

int lim = 0;

while(t > 1)

b[++lim] = 1;

b[lim + 1] = 1;

sort(a + 1, a + 1 + k);

k++;

a[k] = make_pair(n, m);

for (int i = 1; i <= k; i++)

ll ans = 0;

for (int j = 1; j <= lim; j++)

}} }

for (int i = 0; i <= lim; i++)

ans = (ans * qpow(c(n + m - 2, n - 1), mod - 2)) % mod;

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

}

Codeforces 722C 並查集 思維

思路 題目給的運算元從第 1 個到第 n 個數是刪除原陣列中的乙個數,那麼反過來從後往前就是增加原陣列中的乙個數,每增加乙個值,那麼就有四種情況 第一種和前後都不連續,即自成乙個集合 第二種 和前面的數連續,即和前乙個數在乙個集合 第三種和之後乙個數連續,即和之後的乙個數在乙個集合 第四種既和前面乙...

Codeforces 976E 題解報告

1 當把所有的倍數2 a都加到同一health上,health增加的最多 2 先計算每乙個creature的hp dmg,按該值對所有的creature排序 再求和,i include using namespace std const int n 200 1000 9 int hp n dmg n...

codeforces 1030E 暴力 思維)

題目 題意 給定一些數,可將區間 l r 中某些數的二進位制位的1的位置更換,使得最終區間所有數異或和為0,求這樣的區間個數。思路 在那裡瞎dp了好久,wa的很徹底,借鑑了一下別人的思路。區間合法的條件是 這個區間1的個數為偶數,並且區間中二進位制位1最多的乙個數的二進位制個數小於等於和的一半。我們...