zoukankan      html  css  js  c++  java
  • test20181006 投票

    题意


    分析

    考场30分

    枚举大小为k的子集的算法终于用上了。
    时间复杂度

    [Oleft(inom{n}{k} cdot inom {k}{frac{k}{2}} cdot k ight) ]

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> inline T read(T&x)
    {
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=20;
    int n,k;
    double p[MAXN],t[MAXN];
    int len;
    
    int next(int comb)
    {
    	int x = comb & -comb,y = comb + x;
    	comb=(((comb & ~y) / x) >> 1) | y;
    	return comb;
    }
    
    int main()
    {
      freopen("vote.in","r",stdin);
      freopen("vote.out","w",stdout);
    	read(n);read(k);
    	for(int i=0;i<n;++i)
    	{
    		scanf("%lf",p+i);
    	}
    	double maxv=0;
    	for(int i=(1<<k)-1;i<(1<<n);i=next(i))
    	{
    //		cerr<<"i="<<i<<endl;
    		len=0;
    		for(int j=0;j<n;++j)
    			if(i&(1<<j))
    				t[len++]=p[j];
    //		cerr<<"len="<<len<<endl;
    		double ans=0;
    		for(int j=(1<<(len/2))-1;j<(1<<len);j=next(j)) // len=k
    		{
    //			cerr<<" j="<<j<<endl;
    			double sum=1;
    			for(int s=0;s<len;++s)
    			{
    				if(j&(1<<s))
    				{
    //					cerr<<"  mul 1 "<<t[s]<<endl;
    					sum*=t[s];
    				}
    				else
    				{
    					sum*=(1.0-t[s]);
    //					cerr<<"  mul 2 "<<(1.0-t[s])<<endl;
    				}
    			}
    //			cerr<<" sum="<<sum<<endl;
    			ans+=sum;
    		}
    		maxv=max(maxv,ans);
    	}
    	printf("%lf
    ",maxv);
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    

    标解

    解释一下

    1. 所谓的贡献,就是把其他的看成常量,用i同学来计算的计算式。
    2. 换成前后至少有一个不劣。
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #pragma GCC optimize ("O0")
    using namespace std;
    template<class T> inline T read(T&x)
    {
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int MAXN=2e3+7;
    int n,k;
    double p[MAXN],pre[MAXN][MAXN],suf[MAXN][MAXN];
    
    int main()
    {
      freopen("vote.in","r",stdin);
      freopen("vote.out","w",stdout);
    	read(n);read(k);
    	for(int i=1;i<=n;++i)
    		scanf("%lf",p+i);
    	sort(p+1,p+n+1);
    	
    	pre[0][0]=1;
    	for(int i=1;i<=n;++i)
    	{
    		double p=::p[i];
    		for(int j=n;j>=1;--j)
    			pre[i][j]=p*pre[i-1][j-1]+(1-p)*pre[i-1][j];
    		pre[i][0]=(1-p)*pre[i-1][0];
    	}
    	
    	suf[n+1][0]=1;
    	for(int i=n;i>=1;--i)
    	{
    		double p=::p[i];
    		for(int j=n;j>=1;--j) // 从n到1保证不会被自己更新
    			suf[i][j]=p*suf[i+1][j-1]+(1-p)*suf[i+1][j];
    		suf[i][0]=(1-p)*suf[i+1][0];
    	}
    	
    	int m=k/2;
    	double ans=0;
    	for(int i=0;i<=k;++i)
    	{
    		int j=n+1-k+i; // n-x+1=k-i -> x=n+1-k+i
    		double sum=0;
    		for(int ci=0;ci<=m;++ci)
    			sum+=pre[i][ci]*suf[j][m-ci];
    		ans=max(ans,sum);
    	}
    	
    	printf("%.9f
    ",ans);
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    
    静渊以有谋,疏通而知事。
  • 相关阅读:
    sql中where和having的区别
    mysql中locate和substring函数使用
    使用jdk进行数据迁移(sqlite迁移mysql)
    mysql数值函数
    mysql字符串函数
    zabbix-2.2.2(Ubuntu 14.04 LTS/OpenLogic 7.2)
    Piwik-2.16.1 (OpenLogic CentOS7.2)
    Nagios-4.1.1 (OpenLogic CentOS 7.2)
    Bugzilla-5.0.3 (OpenLogic CentOS 7.2)
    GitLab-CE-8.9.4 (OpenLogic CentOS 7.2)
  • 原文地址:https://www.cnblogs.com/autoint/p/9747554.html
Copyright © 2011-2022 走看看