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

    1076: [SCOI2008]奖励关

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2145  Solved: 1153
    [Submit][Status][Discuss]

    Description

      你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关。在这个奖励关里,系统将依次随机抛出k次宝物,
    每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃)。
     宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立。也就是说,即使前k-1次系统都抛出宝物1(
    这种情况是有可能出现的,尽管概率非常小),第k次抛出各个宝物的概率依然均为1/n。 获取第i种宝物将得到Pi
    分,但并不是每种宝物都是可以随意获取的。第i种宝物有一个前提宝物集合Si。只有当Si中所有宝物都至少吃过
    一次,才能吃第i种宝物(如果系统抛出了一个目前不能吃的宝物,相当于白白的损失了一次机会)。注意,Pi可
    以是负数,但如果它是很多高分宝物的前提,损失短期利益而吃掉这个负分宝物将获得更大的长期利益。 假设你
    采取最优策略,平均情况你一共能在奖励关得到多少分值?

    Input

      第一行为两个正整数k和n,即宝物的数量和种类。以下n行分别描述一种宝物,其中第一个整数代表分值,随
    后的整数依次代表该宝物的各个前提宝物(各宝物编号为1到n),以0结尾。

    Output

      输出一个实数,保留六位小数,即在最优策略下平均情况的得分。

    Sample Input

    1 2
    1 0
    2 0

    Sample Output

    1.500000

    HINT

    【数据规模】

    1<=k<=100,1<=n<=15,分值为[-10^6,10^6]内的整数。

    状压+期望DP。
    把每个宝物所需要的宝物压成一个二进制串。
    这个DP需要倒推,因为顺推不好算期望

     f[i][j]表示第i轮状态为j,然后枚举下一轮系统给的宝珠

    判断能不能吃,能吃就是f[i][j]=max(f[i+1][j],f[i+1][j|(1<<(l-1))]+v[l]) 
    (吃或不吃) 不能吃就是
    f[i][j]=f[i+1][j]。最后要除个总宝珠量才是期望。
     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<ctime>
     6 #include<cmath>
     7 #include<string>
     8 #include<vector>
     9 #include<cstdio>
    10 #include<cstdlib>
    11 #include<cstring>
    12 #include<iostream>
    13 #include<algorithm>
    14 using namespace std;
    15 int v[110],p[110];
    16 double f[110][70000];
    17 int main()
    18 {
    19   freopen("!.in","r",stdin);
    20   freopen("!.out","w",stdout);
    21   int n,k,x;
    22   scanf("%d%d",&n,&k);
    23   for(int i=1;i<=k;i++){
    24     scanf("%d",&v[i]);
    25     while(1){
    26       scanf("%d",&x);
    27       if(x==0) break;
    28       p[i]+=(1<<(x-1));
    29     }
    30   }
    31   for(int i=n;i>=1;i--)
    32     for(int j=0;j<(1<<k);j++){
    33       for(int l=1;l<=k;l++)
    34     if((p[l]&j)==p[l])
    35       f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(l-1))]+v[l]);
    36     else f[i][j]+=f[i+1][j];
    37       f[i][j]/=k;
    38     }
    39   printf("%.6lf",f[1][0]);
    40   return 0;
    41 }
    
    
    
     
  • 相关阅读:
    mysql 大数据量求平均值
    mysql 大数据量求平均值
    dhcpd.conf(5)
    dhcpd.conf(5)
    学习记录(文章内容来自相关材料)
    分享一个ASP.NET 文件压缩解压类 C#
    服务降级
    distinct用法
    trim合理和谐
    小娱乐一下,fileInfo中的Name ,FullName的用法小BUG
  • 原文地址:https://www.cnblogs.com/pantakill/p/6653889.html
Copyright © 2011-2022 走看看