zoukankan      html  css  js  c++  java
  • 【JZOJ6296】投票【期望概率】【dp】

    题目大意:

    题目链接:https://jzoj.net/senior/#main/show/6296
    ii个人有pip_i的概率会选择1,否则选择0。求在nn个人中选择mm个,1和0的个数相等的期望。


    思路:

    30pts30pts

    O(3n)O(3^n)暴力搜索每一个人是不选,选1还是选0。用状压记录每一种选择方案的概率。
    空间复杂度O(2n)O(2^n)
    好像O(4n)O(4^n)还可以拿40pts40pts
    代码LinkLink


    100pts100pts

    pip_i排序,如果此时最有方案中存在一个选择的人,他左右均有人且都没有被选择,那么固定其他选择的人,在剩余的人中选择,期望一定为一个一次函数。所以这个人肯定王左或往右会更优。
    所以设f[i][j]f[i][j]表示在[1,i][1,i]中选择jj个人选择1,g[i][j]g[i][j]表示在[i,n][i,n]中选择jj个人选择1。
    ff为例,如果这一个位置选择0,那么f[i][j]=f[i1][j1]×(1p[i])f[i][j]=f[i-1][j-1] imes (1-p[i]),如果这一个位置选择1,那么f[i][j]=f[i1][j1]×p[i]f[i][j]=f[i-1][j-1] imes p[i]
    所以方程就是
    f[i][j]=f[i1][j]×(1p[i])+f[i1][j1]×p[i]f[i][j]=f[i-1][j] imes (1-p[i])+f[i-1][j-1] imes p[i]
    最后枚举前面选多少人,以及前面几个人选1,计算一下答案即可。
    时间复杂度O(nm)O(nm)


    代码:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N=2010;
    double p[N],f[N][N],g[N][N],ans,maxn;
    int n,m;
    
    int main()
    {
    	freopen("vote.in","r",stdin);
    	freopen("vote.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    		scanf("%lf",&p[i]);
    	sort(p+1,p+1+n);
    	f[0][0]=g[n+1][0]=1.0;
    	for (int i=1;i<=n;i++)
    		for (int j=0;j<=m;j++)
    		{
    			if (!j) f[i][j]=f[i-1][j]*(1-p[i]);
    			f[i][j]=f[i-1][j]*(1-p[i])+f[i-1][j-1]*p[i];
    		}
    	for (int i=n;i>=1;i--)
    		for (int j=0;j<=m;j++)
    		{
    			if (!j) g[i][j]=g[i+1][j]*(1-p[i]);
    			g[i][j]=g[i+1][j]*(1-p[i])+g[i+1][j-1]*p[i];
    		}
    	for (int i=0;i<=m;i++)
    	{
    		ans=0.0;
    		for (int j=0;j<=m/2;j++)
    			ans+=f[i][j]*g[n-m+i+1][m/2-j];
    		if (ans>maxn) maxn=ans;
    	}
    	printf("%0.8lf",maxn);
    	return 0;
    }
    
  • 相关阅读:
    flex 弹性盒布局 移动端首页
    less+rem基础使用
    github 本地操作
    git 码云
    react基础知识
    css样式
    uni-app 知识点
    web app
    2019年一半已过,这些大前端技术你都GET了吗?- 下篇
    2019年大前端技术周刊-#31周
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998058.html
Copyright © 2011-2022 走看看