UVALive-8138 Number Generator 概率dp+优化
2018-08-28 23:19
387 查看
题目链接:https://cn.vjudge.net/problem/UVALive-8138
题意
有一个随机数生成器,输出1~n的整数。
现在已经输出了k个数,问再取几个数才能使取出的所有数的个数至少为2。
注意T<=1e5, \sum k<=1e5
思路
(听说存在公式?理论上说有了转移方程和边界,公式就是存在
概率dp,注意状态的选取。
设i为出现0次的数的个数,j为出现1次的数的个数。
\[
\begin{align*}
dp(i, j) &= \frac{i}{n}[dp(i-1, j+1)+1]+\frac{j}{n}[dp(i, j-1)+1]+\frac{n-i-j}{n}[dp(i, j)+1] \\
dp(i, j) &= \frac{i}{i+j}dp(i-1, j+1)+\frac{j}{i+j}dp(i, j-1)+\frac{n}{i+j}
\end{align*}
\]
$ dp(0, 0)=0 $
实际上,n是可以提出来的,这一点还请注意啊。
提交过程
TLE | 状态没选对,导致n没提出来 |
AC |
代码
#include <cstdio> #include <cstring> const int maxn=3e3+20; const int INF=0x3f3f3f3f; double data[maxn][maxn]; int n, k; double dp(int i, int j){ if (i==0 && j==0) return 0; if (data[i][j]>0) return data[i][j]; data[i][j]=1; if (i>=1) data[i][j]+=i*dp(i-1, j+1); if (j>=1) data[i][j]+=j*dp(i, j-1); data[i][j]/=(double)(i+j); return data[i][j]; } int main(void){ int T, tmp; scanf("%d", &T); while (T--){ scanf("%d%d", &n, &k); int vis[maxn]={0}; for (int i=0; i<k; i++){ scanf("%d", &tmp); vis[tmp]++; } int cnt_1=0, cnt_0=0; for (int i=1; i<=n; i++){ if (vis[i]==1) cnt_1++; else if (vis[i]==0) cnt_0++; } printf("%.6f\n", n*dp(cnt_0, cnt_1)); } return 0; }
Time | Memory | Length | Lang | Submitted |
---|---|---|---|---|
449ms | None | 827 | C++ 5.3.0 | 2018-08-28 13:23:33 |
相关文章推荐
- UVALive 6624 Card Trick (概率DP)
- UVALive 6624 - Card Trick - 概率dp
- UVALive 6620 Josephina and RPG(概率DP)
- UVaLive 4327 | POJ 3926 - Parade (单调队列优化DP)
- UVALive 6514:Crusher’s Code(概率dp)
- UvaLive 5811 概率DP
- POJ 2018 Best Cow Fences + UVA Live 4726 Average 斜率优化DP
- UVALive 6175 Maximum Random Walk 期望+概率dp
- UVALive 3983(单调队列优化dp)
- uva live 6190 Beautiful Spacing (二分+dp检验 根据特有性质优化)
- uvalive5721 Activation(概率dp)
- DP(优化) UVALive 6073 Math Magic
- UVaLive 4731 UVa 1456 - Cellular Network(概率DP 贪心)
- UVA live - 4327(滑动队列优化dp)
- UVa1637 - Double Patience(概率+dp)
- uvalive3516(DP)
- UVA - 1427(经典滑动队列优化dp)
- UvaLive 6441 Horrible Quiz(dp)
- UVALive 2038 Strategic game (树形DP,4级)
- UVA - 1169(滑动队列优化dp)