zoukankan      html  css  js  c++  java
  • 【[SCOI2008]奖励关】

    又抄了一篇题解

    要凉了要凉了,开学了我还什么都不会

    文化课凉凉,NOIP还要面临爆零退役的历史进程

    这道题挺神的,期望+状态压缩

    我们设(dp[i][S])表示在第(i)天前,捡的宝物状态为(S)到第(K)天结束的期望收益是多少

    于是我们的答案是(dp[1][0]),也就是第一天前(就是没开始)什么宝物也没有到结束的期望是多少

    期望倒着推,我们的初始状态就是(dp[k+1]={0})

    之后对于一个状态(dp[i][S])

    在第(i)(m)种宝物出现的概率都是(1/m)

    所以枚举每一种宝物(j),如果这个宝物的前提条件被(S)包含

    就有

    [dp[i][S]+=max(dp[i+1][S|(1<<(j-1))]+val[j],dp[i+1][S])*1/m ]

    就是就算可以选择这个宝物的话,我们也两种选择拿或者不拿这个宝物

    如过没有被包含,你只能不拿这个宝物

    [dp[i][S]+=dp[i+1][S]*1/m ]

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define re register
    #define max(a,b) ((a)>(b)?(a):(b))
    inline int read()
    {
    	char c=getchar();
    	int x=0,r=1;
    	while(c<'0'||c>'9') 
    	{
    		if(c=='-') r=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9')
    	  x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x*r;
    }
    double dp[102][32769];
    int n,m,N;
    int cost[16];
    int f[16];
    int main()
    {
    	n=read(),m=read();
    	for(re int i=1;i<=m;i++)
    	{
    		cost[i]=read();
    		int x=read(),y=0;
    		while(x) y|=1<<(x-1),x=read();
    		f[i]=y;
    	}
    	N=(1<<m)-1;
    	for(re int i=0;i<=N;i++) dp[n+1][i]=0;
    	for(re int i=n;i;i--)
    	for(re int j=0;j<=N;j++)
    	{
    		for(re int k=1;k<=m;k++)
    		if(((f[k]|j)==j))
    		{
    			dp[i][j]+=max(dp[i+1][j],dp[i+1][j|(1<<(k-1))]+cost[k])/double(m);
    		}else dp[i][j]+=dp[i+1][j]/double(m);
    	}
    	printf("%.6lf",dp[1][0]);
    	return 0;
    }
    
  • 相关阅读:
    测试脚本
    浅谈优化SQLServer数据库服务器内存配置的策略
    真正的取真实IP地址及利弊Asp.net
    ASP.NET一些常用正则表达式
    (CHMSoftware)工具集锦
    仿真方面的文章
    TPlan测试过程管理工具技术摘要
    Linux 2.6内核的精彩世界(多媒体)
    Ajax技术实践之完成Ajax自动完成功能
    硬件测试
  • 原文地址:https://www.cnblogs.com/asuldb/p/10206231.html
Copyright © 2011-2022 走看看