v

题目背景

\(\frac 14\)遇到了一道水题,又完全不会做,于是去请教小\(\text{D}\)。小\(\text{D}\)看了\(0.607\)眼就切掉了这题,嘲讽了\(\frac 14\)一番就离开了。

于是,\(\frac 14\)只好来问你,这道题是这样的:

题目描述

有\(n\)个球排成一行,每个球的颜色为黑或白。

执行\(k\)次操作,第\(i(1\le i\le k)\)次操作形式如下:

• 从\([1,n-i+1]\)中,等概率随机选择一个整数\(x\)。

• 移除从左往右数的第\(x\)个球,或从右往左数的第\(x\)个球(也就是从左往右数的第\(n-i+2-x\)个)。之后,所有右侧的球的编号减\(1\)。

给定每个球的颜色信息,希望最大化移除的白球数量。

输出在最优策略下,期望的移除白球数量。误差在\(10^{-6}\)范围内,即算正确。

输入输出格式

输出格式

从文件v.in中读入数据。

第一行,两个整数\(n,k\)。

第二行,一个长度为\(n\)、仅由'W''B'组成的字符串,第\(i\)个字符代表第\(i\)个球的颜色,'W'为白色,'B'为黑色。

输入格式

输出到文件v.out中。

输出一行,一个浮点数,代表答案。

说明

数据范围

保证\(1\le n\le 30\),\(0\le k\le n\)。

\(\text{Subtask}\) 分值 \(n\le\) 其他限制
\(1\) \(20\) \(5\)
\(2\) \(25\) \(20\)
\(3\) \(1\) \(30\) 保证\(k=0\)或\(k=n\)
\(4\) \(1\) \(30\) 保证字符串所有字符相同
\(5\) \(19\) \(30\) 保证字符串只有一个'W'
\(6\) \(19\) \(30\) 保证字符串只有一个'B'
\(7\) \(15\) \(30\)

挂了一堆部分分。。。惨无人道啊。

45pts状压一下

\(dp_{i,sta}=\sum max(dp_{i-1,to1},dp_{i-1,to2})\)

因为要倒着做所以直接记搜就行了

剩下的部分分瞎搞一下

100pts就是把状态存储小的用数组存,大的用map...

我太菜而最后一个点实在是卡不过去了


Code:

#include <cstdio>
#include <cstring>
#include <map>
int n,k;
std::map <int,double> dp[31];
double dp0[24][1<<23];
char s[32];
double max(double x,double y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
double dfs(int sta,int siz)
{
if(siz==n-k) return 0;
if(siz>23&&dp[siz].find(sta)!=dp[siz].end()) return dp[siz][sta];
if(siz<=23&&dp0[siz][sta]!=-1.0) return dp0[siz][sta];
double sum=0;
for(int i=1;i<=siz>>1;i++)
{
int co1=sta>>i-1&1,co2=sta>>siz-i&1;
int to1=sta>>1&~((1<<i-1)-1)|sta&(1<<i-1)-1;
int to2=sta>>1&~((1<<siz-i)-1)|sta&((1<<siz-i)-1);
sum+=2*max(dfs(to1,siz-1)+co1,dfs(to2,siz-1)+co2);
}
if(siz&1)
{
int i=siz+1>>1;
int to=sta>>1&~((1<<i-1)-1)|sta&(1<<i-1)-1;
int co=sta>>i-1&1;
sum+=dfs(to,siz-1)+co;
}
sum=sum/siz;
return siz>23?dp[siz][sta]=sum:dp0[siz][sta]=sum;
}
int main()
{
scanf("%d%d%s",&n,&k,s);
int st=0;
for(int i=n-k+1;i<=min(23,n);i++)
for(int j=0;j<1<<i;j++)
dp0[i][j]=-1.0;
for(int i=1;i<=n;i++)
st|=(s[i-1]=='W')<<n-i;
printf("%.8lf\n",dfs(st,n));
return 0;
}

2018.10.3

UPT on 2018.10.12:我卡过去了,并且学会了一个小技巧

发现状态数组实际上有很多浪费,因为每个\(i\)的状态都是\(2^i\)的,我们没必要开两维

直接开一维\(dp_{sta}\)就可以。

但是这样可能造成重复之类的,我们可以给某一个长度为\(i\)的维度把\(i+1\)位打1标记,代表这是第\(i\)维的

这是很常见的一个技巧了

Code:

// luogu-judger-enable-o2
#include <cstdio>
#include <cstring>
#include <map>
int n,k;
std::map <int,double> dp;
double dp0[1<<25];
char s[32];
double max(double x,double y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
double dfs(int sta,int siz)
{
if(siz==n-k) return 0;
if(siz>24&&dp.find(sta)!=dp.end()) return dp[sta];
if(siz<=24&&dp0[sta]!=-1.0) return dp0[sta];
double sum=0;
for(int i=1;i<=siz>>1;i++)
{
int co1=sta>>i-1&1,co2=sta>>siz-i&1;
int to1=sta>>1&~((1<<i-1)-1)|sta&(1<<i-1)-1;
int to2=sta>>1&~((1<<siz-i)-1)|sta&((1<<siz-i)-1);
sum+=2.0*max(dfs(to1,siz-1)+co1,dfs(to2,siz-1)+co2)/siz;
}
if(siz&1)
{
int i=siz+1>>1;
int to=sta>>1&~((1<<i-1)-1)|sta&(1<<i-1)-1;
int co=sta>>i-1&1;
sum+=(dfs(to,siz-1)+co)/siz;
}
return siz>24?dp[sta]=sum:dp0[sta]=sum;
}
int main()
{
scanf("%d%d%s",&n,&k,s);
int st=0;
for(int i=0;i<1<<25;i++)
dp0[i]=-1.0;
for(int i=1;i<=n;i++)
st|=(s[i-1]=='W')<<n-i;
st|=1<<n;
printf("%.8lf\n",dfs(st,n));
return 0;
}

雅礼集训 Day3 T2 v 解题报告的更多相关文章

  1. 雅礼集训 Day3 T2 u 解题报告

    u 题目背景 \(\frac 14\) 遇到了一道水题,完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了一眼就切掉了这题,嘲讽了\(\frac 14\)一番就离开了. ...

  2. 雅礼集训 Day3 T3 w 解题报告

    w 题目背景 \(\frac 14\)遇到了一道水题,双完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了\(0.607^2\)眼就切掉了这题,嘲讽了\(\frac 14 ...

  3. 雅礼集训 Day6 T2 Equation 解题报告

    Equation 题目描述 有一棵\(n\)个点的以\(1\)为根的树,以及\(n\)个整数变量\(x_i\).树上\(i\)的父亲是\(f_i\),每条边\((i,f_i)\)有一个权值\(w_i\ ...

  4. 「雅礼集训 2017 Day2」解题报告

    「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...

  5. 「雅礼集训 2017 Day1」 解题报告

    「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...

  6. 雅礼集训 Day1 T3 画作 解题报告

    画作 题目描述 小\(\mathrm{G}\)的喜欢作画,尤其喜欢仅使用黑白两色作画. 画作可以抽象成一个\(r\times c\)大小的\(01\)矩阵.现在小\(\mathrm{G}\)构思好了他 ...

  7. 雅礼集训 Day5 T3 题 解题报告

    题 题目背景 由于出题人赶时间所以没办法编故事来作为背景. 题目描述 一开始有\(n\)个苹果,\(m\)个人依次来吃苹果,第\(i\)个人会尝试吃\(u_i\)或\(v_i\)号苹果,具体来说分三种 ...

  8. 雅礼集训 Day2 T3 联盟 解题报告

    联盟 题目描述 \(\text{G}\) 国周边的 \(n\) 个小国家构成一个联盟以抵御 \(\text{G}\) 国入侵, 为互相支援,他们建立了\(n−1\) 条双向通路, 使得任意两个国家可以 ...

  9. 雅礼集训 Day7 T1 Equation 解题报告

    Reverse 题目背景 小\(\text{G}\)有一个长度为\(n\)的\(01\)串\(T\),其中只有\(T_S=1\),其余位置都是\(0\).现在小\(\text{G}\)可以进行若干次以 ...

随机推荐

  1. Salt-ssh 自动安装salt-minion

    作用:为了不手动去安装一台一台去salt-minion,并进重复的配置 一.环境 系统环境: #cat /etc/redhat-release CentOS Linux release 7.4.170 ...

  2. 差点掉坑,MySQL一致性读原来是有条件的

    众所周知,在设定了隔离等级为Repeatable Read及以上时,InnoDB 可以实现数据的一致性读.换句话来说,就是事务执行的任意时刻,读取到的数据是同一个快照,不会受到其他事务的更新影响. 以 ...

  3. 华为模拟器ensp代码错误2,41,40问题的解决

    win8+ensp320 ensp这是个神奇的软件,问题竟然出现的这么莫名其妙..前一秒还是好的时候,后一秒就立马出现了问题.不过不要慌...沉住气,把这篇文章看下去. 博主从昨天开始,ensp神奇的 ...

  4. C语言进阶—— 接续符和转义符13

    接续符的意义: C语言中的接续符 (\) 是指示编译器行为的利器 我们来看一个案例: #in\ clud\ e <st\ dio.h> in\ t m\ ain(\ ) { pri\ nt ...

  5. Python 外部函数调用库ctypes简介

    Table of Contents 1. 参考资料 2. ctypes简介 2.1. 数据类型 2.2. 调用.so/.dll 2.2.1. 加载动态链接库 2.2.2. 调用加载的函数 2.2.3. ...

  6. 2,Flask 中的 Render Redirect HttpResponse

    一,Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返回字符串 二,.Flask中的Redirect 每当访问"/redi" ...

  7. .Net Mvc 4 Route路由

    1.前言 在创建一个MVC项目后就可以,在App_Start文件下的RouteConfig.cs里面就可以定义我们的路由规则,其中已经有默认的路由规则了,routes.IgnoreRoute是让路由规 ...

  8. Android自定义组件之简单组合

    Android自定义控件有两种,一种是组合.比如一个linearlayout 里面有textview,imageview. 这样的好处是,写一个就可以多处使用. view_image_and_butt ...

  9. 读json文件发生错误,所遇到的坑

    当我们生产者生产json 文件的时候   消费时用JSON读文件时,如下: val values = kafkardd.map(t=>JSON.parseObject(t._2)) 如果发生以下 ...

  10. 滑动菜单栏之开源项目SlidingMenu的使用

    一.SlidingMenu简介 相信大家对SlidingMenu都不陌生了,它是一种比较新的设置界面或配置界面的效果,在主界面左滑或者右滑出现设置界面效果,能方便的进行各种操作.很多优秀的应用都采用了 ...