文章目录
2020-2021 ACM-ICPC Brazil Subregional Programming Contest
A.Sticker Album
题意: 给你一个容量为n的卡牌收集册,以及无限个卡牌包,卡牌包有[a,b]个卡牌,取出的卡牌数是等概率分布的,言外之意你有 1 b − a + 1 {\frac{1}{b-a+1}} b−a+11的概率取出a、a+1、…、b张卡牌。问你把卡牌收集册集满时的概率期望是多少。
题解: 动态规划,设 d p [ i ] dp[i] dp[i]:已经有i张手牌,要集满n张还需要的卡牌数目。转移方程为: d p [ i ] = ( d p [ i + a ] + 1 ) + ( d p [ i + a + 1 ] + 1 ) + . . . + ( d p [ i + b ] + 1 ) b − a + 1 = d p [ i + a ] + d p [ i + a + 1 ] + . . . + d p [ i + b ] b − a + 1 + 1 dp[i] = \frac{(dp[i + a] + 1) + (dp[i + a + 1] + 1) + ... + (dp[i + b] + 1)}{b - a + 1} = \frac{dp[i+a] + dp[i+a+1] + ... + dp[i+b]}{b - a+ 1} + 1 dp[i]=b−a+1(dp[i+a]+1)+(dp[i+a+1]+1)+...+(dp[i+b]+1)=b−a+1dp[i+a]+dp[i+a+1]+...+dp[i+b]+1
然而当a=0时会出现问题,那么式子为: d p [ i ] = ( d p [ i ] + 1 ) + ( d p [ i + 1 ] + 1 ) + . . . + ( d p [ i + b ] + 1 ) b − 1 dp[i] = \frac{(dp[i] + 1) + (dp[i + 1] + 1) + ... + (dp[i + b] + 1)}{b - 1} dp[i]=b−1(dp[i]+1)+(dp[i+1]+1)+...+(dp[i+b]+1),转换为: d p [ i ] = ( d p [ i + 1 ] + d p [ i + 2 ] + . . . d p [ i + b ] b − a + 1 + 1 ) ∗ l l − 1 dp[i] = (\frac{dp[i + 1] + dp[i + 2] + ...dp[i+b]}{b - a + 1} + 1) * \frac{l}{l-1} dp[i]=(b−a+1dp[i+1]+dp[i+2]+...dp[i+b]+1)∗l−1l
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {
int s = 0, w = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') w = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}
int const MAXN = 2e6 + 10;
int n, m, T, a, b;
double dp[MAXN];
signed main() {
int n, a, b, len;
cin >> n >> a >> b;
len = b - a + 1;
dp[n] = 0.0;
double sum = 0.0;
for (int i = n - 1; i >= 0; i--) {
if (!a) {
dp[i] = (sum + len * 1.0) / (len - 1.0);
sum -= dp[i + b];
sum += dp[i];
}