题目背景

  $\frac{1}{4}$遇到了一道水题,又完全不会做,于是去请教小$D$。小$D$看了$0.607$眼就切掉了这题,嘲讽了$\frac{1}{4}$一番就离开了。于是,$\frac{1}{4}$只好来问你,这道题是这样的:


题目描述

  有$n$个球排成一行,每个球的颜色为黑或白。
  执行$k$次操作,第$i(1\leqslant i\leqslant k)$次操作形式如下:
  $\bullet$从$[1,n−i+1]$中,等概率随机选择一个整数$x$。
  $\bullet$移除从左往右数的第$x$个球,或从右往左数的第$x$个球(也就是从左往右数的第$n−i+2−x$个)。之后,所有右侧的球的编号减$1$。
  给定每个球的颜色信息,希望最大化移除的白球数量。
  输出在最优策略下,期望的移除白球数量。误差在${10}^{−6}$范围内,即算正确。


输入格式

从文件$v.in$中读入数据。
第一行,两个整数$n,k$。
第二行,一个长度为$n$、仅由$'W'$和$'B'$组成的字符串,第$i$个字符代表第$i$个球的颜色,$'W'$为白色,$'B'$为黑色。


输出格式

输出到文件$v.out$中。
输出一行,一个浮点数,代表答案。


样例

样例输入1:

3 1
BWW

样例输出1:

1.0000000000

样例输入2:

4 2
WBWB

样例输出2:

1.5000000000


数据范围与提示

样例$1$解释:

如果$x=1$,从右侧操作,如果$x=2$或$3$,从左侧操作,均可以移除一个白球。

数据范围:

保证$1\leqslant n\leqslant 30,0\leqslant k\leqslant n$。


题解

先来看$20$分的做法,我们可以使用状压$DP$解决,即为:

$$dp[i][sta]=\sum \max (dp[i-1][sta'],dp[i-1][sta"])$$

剩下的我们可以记忆化搜索,用$map$存储已经出现过了的状态,加快转移速度。

但是这道题的数据卡了$map$,所以我们可以考虑$unordered_map+$大力卡常或者是手打$hash_map$,建议选择后者,既锻炼了手打$hash_map$的能力,又能感受到轻松$AC$此题的快感(不用卡常)。

状态数最多只有$\sum \limits_{i=0}^n\min\{2^i,C_n^i\}$,即为$\sum \limits_{i=1}^{n+1}Fib(i)$。

时间复杂度:$\Theta(\sum \limits_{i=1}^{n+1}Fib(i)\times n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to,w;double v;};
struct hash_mp
{
int head[40000000],cnt;
rec e[6000000];
int len;
double &operator[](int sta)
{
int key=1LL*sta*len%30000019;
for(int i=head[key];i;i=e[i].nxt)
if(e[i].to==sta&&e[i].w==len)return e[i].v;
e[++cnt].nxt=head[key];
e[cnt].to=sta;
e[cnt].w=len;
e[cnt].v=-1.0;
head[key]=cnt;
return e[cnt].v;
}
}mp;
int n,k;
char ch[31];
int st;
double dfs(int x,int sta)
{
if(x==n-k)return 0.0;
mp.len=x;
if(mp[sta]>-0.5)return mp[sta];
mp[sta]=0;
st=sta;
bool Map[31];
for(int i=1;i<=x;i++)
{
Map[i]=st&1;
st>>=1;
}
for(int i=1;i<=x/2;i++)
{
double flag1=dfs(x-1,((sta>>(x-i+1))<<(x-i))|(sta&((1<<x-i)-1)))+Map[x-i+1];
double flag2=dfs(x-1,((sta>>i)<<(i-1))|(sta&((1<<i-1)-1)))+Map[i];
mp.len=x;
mp[sta]+=2.0/x*max(flag1,flag2);
}
if(x&1)
{
double flag=dfs(x-1,(sta>>(x-((x>>1)+1)+1))<<(x-((x>>1)+1))|(sta&((1<<(x-((x>>1)+1)))-1)))+Map[x/2+1];
mp.len=x;
mp[sta]+=1.0/x*flag;
}
return mp[sta];
}
int main()
{
scanf("%d%d%s",&n,&k,ch+1);
k=min(n,k);
for(int i=1;i<=n;i++)
{
st<<=1;
if(ch[i]=='W')
st++;
}
printf("%.10lf",dfs(n,st));
return 0;
}

rp++

[CSP-S模拟测试]:v(hash表+期望DP)的更多相关文章

  1. [CSP-S模拟测试]:环(图论+期望)

    题目传送门(内部题79) 输入格式 第一行读入两个整数$n,e$表示节点数及$cwystc$已确定的有向边边数. 接下来$e$行,每行两个整数$x,y$描述$cwystc$确定的边. 输出格式 输出一 ...

  2. [CSP-S模拟测试]:二叉搜索树(DP+贪心)

    题目传送门(内部题99) 输入格式 第一行一个整数$n$,第二行$n$个整数$x_1\sim x_n$. 输出格式 一行一个整数表示答案. 样例 样例输入: 58 2 1 4 3 样例输出: 数据范围 ...

  3. [CSP-S模拟测试]:城市游戏(图论+DP)

    题目传送门(内部题109) 输入格式 第一行,两个整数$n,m$. 接下来$m$行,每行三个整数$u,v,l$,描述了一条道路连接的两个路口的编号以及道路的长度. 输出格式 输出一行一个整数,为所求的 ...

  4. [CSP-S模拟测试]:旅行计划(分块+DP)

    题目传送门(内部题83) 输入格式 第一行两个整数$n,m$ 接下来$m$行,每行三个整数,$u,v,w$,表示从$u$到$v$有一条权值为$w$的边 接下来一行有一个整数$q$,表示$q$天 接下来 ...

  5. [CSP-S模拟测试]:糊涂图(概率DP)

    题目传送门(内部题76) 输入格式 第一行输入三个空格隔开的整数$n,m,s$表示随机加一条边之前的糊涂图的点数,边数,以及起点的编号. 接下来$m$行,每行两个空格隔开的整数$a,b$表示从$a$到 ...

  6. [CSP-S模拟测试]:抽卡(概率DP)

    题目描述 水上由岐最近在肝手游,游戏里有一个氪金抽卡的活动.有$n$种卡,每种卡有 3 种颜色.每次抽卡可能什么也抽不到,也可能抽到一张卡.每氪金一次可以连抽 m 次卡,其中前$m−1$次抽到第$i$ ...

  7. [2016北京集训测试赛5]azelso-[概率/期望dp]

    Description Solution 感谢大佬的博客https://www.cnblogs.com/ywwyww/p/8511141.html 定义dp[i]为[p[i],p[i+1])的期望经过 ...

  8. [CSP-S模拟测试]:装饰(状压DP)

    题目传送门(内部题114) 输入格式 第一行一个正整数$n$. 接下来一行$n-1$个正整数,第$i$个数为$f_{i+1}$. 接下来一行$n$个数,若第$i$个数为$0$则表示林先森希望$i$号点 ...

  9. [CSP-S模拟测试]:取石子(博弈论+DP)

    题目描述 有三堆石子,它们的石子个数分别为$x,y,z$.$A$和$B$正在博弈,由$A$先手,双方轮流操作.每次操作是指,选择若干堆($1-3$堆)石子,从中各取出相同数量的石子(不能$1$个都不取 ...

随机推荐

  1. Altium Designer chapter3总结

    绘制电路原理图中需要注意的如下: (1)元件库的操作:元件库的加载和卸载.查找元件. (2)元件操作: 1.放置元件(元件库中,place part,快捷键)中place part中的history可 ...

  2. C#获取本地路径

    /// <summary> /// 本地路径 /// </summary> /// <param name="path"></param& ...

  3. k-meanas原理自实现

    import numpy as np import matplotlib.pyplot as plt def build_data(): """ 准备数据 :return ...

  4. Struts2之校验

    ##1.输入校验 错误提示页面 <%@ page language="java" contentType="text/html; charset=UTF-8&quo ...

  5. vue.js2.0 (简易)水果商城 vuex vant-ui

    vue.js2.0 (简易)水果商城 vuex vant-ui:https://segmentfault.com/a/1190000015690250 vue2.5全家桶 高仿vivo商城 百分之95 ...

  6. Ubuntu18.04+CUDA9.0+cuDNN7.1.3+TensorFlow1.8 安装总结

    Ubuntu18.04发行已经有一段时间了,正好最近Tensorflow也发布了1.8版本,于是决定两个一起装上,以下是安装总结,大致可 以分为5个步骤 确认当前软件和硬件环境.版本 更新显卡驱动,软 ...

  7. 屏蔽命令任何输出的:>/dev/null 2>&1

  8. psfstriptable - 从控制台字体中移走嵌入的Uniocde字符表

    总览 psfstriptable 字体文件 [输出文件] 描述 psfstriptable 命令从 字体文件 或者标准输入(此时的 字体文件 是单个破折号(-))读取一个可能含有嵌入Unicode字体 ...

  9. pandas-同时处理两行数据

    pandas-同时处理两行数据 假设数据集data如下所示: 如果我们想要将user_id 和 item_id两列进行对应元素相加的操作,该怎么办呢? 显然我们先定义一个加法函数,然后使用apply函 ...

  10. 查看linux服务器的版本信息

    查看linux系统信息 uname -a Linux localhost.localdomain 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UT ...