首页 > 其他分享 >收集卡牌(期望DP、状态压缩)

收集卡牌(期望DP、状态压缩)

时间:2022-08-26 16:11:16浏览次数:98  
标签:硬币 压缩 卡牌 leq state 抽卡 include DP

题意

小林在玩一个抽卡游戏,其中有\(n\)种不同的卡牌,编号为\(1\)到\(n\)。

每一次抽卡,她获得第\(i\)种卡牌的概率为\(p_i\)。

如果这张卡牌之前已经获得过了,就会转化为一枚硬币。

可以用\(k\)枚硬币交换一张没有获得过的卡。

小林会一直抽卡,直至集齐了所有种类的卡牌为止,求她的期望抽卡次数。

如果你给出的答案与标准答案的绝对误差不超过\(10^{−4}\),则视为正确。

提示:聪明的小林会把硬币攒在手里,等到通过兑换就可以获得剩余所有卡牌时,一次性兑换并停止抽卡。

题目链接:https://www.acwing.com/problem/content/4012/

数据范围

\(1 \leq n \leq 16\)
\(1 \leq k \leq 5\)
\(\sum\limits_{i=1}^n p_i = 1\)

思路

期望DP。首先我们分析一下状态定义。如果没有硬币这个设定,状态就是\(S\),记录已经获得了哪些牌。现在加上硬币这个设定,那么我们再加一维状态,表示已经获得了多少金币。

定义\(f(S, j)\)表示当前卡牌获得情况为\(S\),并且已经获得了\(j\)枚硬币的情况下,还需要抽卡次数的期望。

我们令\(r\)表示\(S\)的二进制表示中\(0\)的个数,因此终止状态为\(j \geq rk\)。

下面考虑转移方程。如果当前摸到的牌之前已经摸到过了,则\(f(S, j) = f(S, j) + p_i * (f(S, j + 1) + 1)\);如果当前摸到的牌之前没有摸过,则\(f(S, j) = f(S, j) + p_i * (f(S | 2^i, j) + 1)\)。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;

const int N = 16, M = 1 << N;

int n, k;
double a[N];
double f[M][5 * N + 10];

double dfs(int state, int coins)
{
    double &v = f[state][coins];
    if(v >= 0) return v;
    int r = n;
    for(int i = 0; i < n; i ++) {
        if(state >> i & 1) {
            r --;
        }
    }
    if(coins >= r * k) return v = 0;
    v = 0;
    for(int i = 0; i < n; i ++) {
        if(state >> i & 1) v += a[i] * (dfs(state, coins + 1) + 1);
        else v += a[i] * (dfs(state | (1 << i), coins) + 1);
    }
    return v;
}

int main()
{
    scanf("%d%d", &n, &k);
    for(int i = 0; i < n; i ++) scanf("%lf", &a[i]);
    memset(f, -1, sizeof f);
    printf("%.10f\n", dfs(0, 0));
    return 0;
}

标签:硬币,压缩,卡牌,leq,state,抽卡,include,DP
From: https://www.cnblogs.com/miraclepbc/p/16627867.html

相关文章

  • leetcode-416-dp
    /**<p>给你一个<strong>只包含正整数</strong>的<strong>非空</strong>数组<code>nums</code>。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相......
  • python内置模块tarfile模块详解:tarfile模块是Python的标准模块之一,能够方便读取tar归
    前言1、通常来说,在工作中我们遇到的最多的压缩文件格式只有5种,如下: xxx.gz 、 xxx.tar 、 xxx.tgz 、 xxx.zip 、 xxx.rar 2、各种压缩文件格式的简介:①gz:......
  • Udp通信
    多发多收clientpackageClientDemo;importjava.net.DatagramPacket;importjava.net.DatagramSocket;importjava.net.InetAddress;importjava.util.Scanner;p......
  • 状态压缩 DP 学习笔记【入门篇】
    前言状态压缩DP,简称状压DP。之前一直觉得状压特别难,学了一下,发现基本形态挺简单的。在学习之前,你需要掌握:简单DP(如线性DP,背包)基本二进制运算:&运算、|运算、\(......
  • 基于 .NET 6 的轻量级 Webapi 框架 FastEndpoints
    大家好,我是等天黑。FastEndpoints 是一个基于.NET6开发的开源webapi框架,它可以很好地替代.NETMinimalAPIs和MVC,专门为开发效率而生,带来了全新的开发模式和编......
  • 【DP】决策单调性小记
    何谓决策单调性?指的就是在最优化dp中,状态的最优转移点单调不减的性质。这使得我们在做dp的时候可以减少冗余计算以达到优化的效果。这类优化方法常用于分段问题。0x......
  • 线程池ThreadPoolExecutor
    线程池ThreadPoolExecutor1、线程池介绍1.1线程池概念Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关......
  • 质因数+树形DP例题
    题目:https://www.codechef.com/submit/MAKEIT1?tab=statement题解:https://www.codechef.com/submit/ROCKET_PACK?tab=solution代码:#include<bits/stdc++.h>#includ......
  • java实现压缩zip包
    1packagecom.common.util;23importjava.io.File;45importjava.io.FileInputStream;67importjava.io.FileOutputStream;89import......
  • CountDownLatch+ThreadPool 优化统计报表
    一、功能要求业务方要求每天发一个统计日报到用户邮箱、业务为统计每日的多项市场指标数据,因为数据表中数据量庞大,每项指标的SQL是单独的逻辑,所以要在一个接口内执行多个S......