zoukankan      html  css  js  c++  java
  • [BZOJ1076][SCOI2008]奖励关解题报告|状压DP

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

      其实题目有个地方刚开始没看懂...

      刚开始说了你必须在跑出下一个宝物之前做出选择,然后我以为和执行最优策略矛盾了...

      事实上你所得到的都是期望得分

      必须在跑出下一个宝物之前作出选择,是因为游戏的具体过程是由系统操作的我们不清楚

      而执行最优策略只要在系统执行的一些概率条件下 作出能够得到最大期望得分的操作

      我们考虑倒序DP

      枚举当前是哪一轮,以及作出选择之前n个数取与不取的状态是怎样的

      再枚举这一轮系统抛下的宝物是哪一件

      如果满足这个宝物可以取,就在取与不取之间作取舍,如果不可以取,就只能不取

      最后再思考一个问题

      题目中有一句话“现在决定不吃的宝物以后也不能再吃”,这个限制在DP过程中并没有体现

      另外要注意,这个条件限制存在仅当目前这个宝物可以吃,也就是我们有自主选择的权利

      然而仔细想一想便可知是不存在问题的

      因为当前可以吃的宝物,以后一定也可以吃,因为已经满足了前提宝物集合的条件

      然而现在吃掉,在以后还可以吃一些前提宝物集合为当前宝物的宝物

      所以当前吃掉一定比以后吃掉的策略要优秀

      所以在执行最优决策的过程中是不存在现在不吃以后吃的情况的~

     1 program bzoj1076;
     2 const maxn = 110;maxm = 32768;
     3 var i,k,n,x,j,p:longint;
     4     w:array[-1..maxn]of longint;
     5     a:array[-1..20,-1..20]of longint;
     6     vis:array[-1..20,-1..maxm]of boolean;
     7     f:array[-1..maxn,-1..maxm]of extended;
     8 
     9 function ok(x,y:longint):boolean;
    10 var i:longint;
    11     tmp:array[-1..20]of longint;
    12 begin
    13     for i:=1 to n do tmp[i]:=y >> (n-i) and 1;
    14     for i:=1 to a[x,0] do if tmp[a[x,i]]=0 then exit(false);
    15     exit(true);
    16 end;
    17 
    18 function max(a,b:extended):extended;
    19 begin
    20     if a>b then exit(a) else exit(b);
    21 end;
    22 
    23 begin
    24     readln(k,n);
    25         fillchar(a,sizeof(a),0);
    26     for i:=1 to n do
    27     begin
    28         read(w[i]);
    29         read(x);
    30         while x<>0 do
    31         begin
    32             inc(a[i,0]);
    33             a[i,a[i,0]]:=x;
    34             read(x);
    35         end;
    36         readln;
    37     end;
    38     for i:=1 to n do
    39         for j:=0 to 1 << n-1 do vis[i,j]:=ok(i,j);
    40     for i:=k downto 1 do //i表示当前进行到第i轮
    41         for j:=0 to 1 << n-1 do //n件物品取与不取的状态
    42         begin
    43             for p:=1 to n do if vis[p,j] then f[i,j]:=f[i,j]+max(f[i+1,j],f[i+1,j or (1 << (n-p))]+w[p]) else f[i,j]:=f[i,j]+f[i+1,j];
    44             f[i,j]:=f[i,j]/n;
    45         end;
    46     writeln(f[1,0]:0:6);
    47 end.
  • 相关阅读:
    百度mp3地址解密码
    VB 在EXE后附加信息
    截屏函数
    Base64和StrToByte
    The Android ION memory allocator, DMABUF is mentioned as well
    DDC EDID 介绍
    Memory management for graphic processors TTM的由来
    科普 写display driver的必看 How video card works [2D的四种主要操作]
    GEM vs TTM
    DMABUF 背景介绍文章 Sharing buffers between devices
  • 原文地址:https://www.cnblogs.com/mjy0724/p/4480203.html
Copyright © 2011-2022 走看看