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;
    }
    
  • 相关阅读:
    ORACLE【0】:基本操作
    ORACLE【3】:分区表以及分区索引
    ORACLE【2】:锁机制及解锁
    log4j学习一:解决系统日志错位问题
    使用一个非堵塞的socket用于接收http请求
    Python中文转换报错 'ascii' codec can't decode byte 0xe8 in position
    首次使用Redis记录【3】
    xsi:schemaLocation有何作用
    【转】【redis】3.Spring 集成注解 redis 项目配置使用
    maven仓库地址
  • 原文地址:https://www.cnblogs.com/asuldb/p/10206231.html
Copyright © 2011-2022 走看看