雅礼集训 Day3 T2 v 解题报告
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 解题报告的更多相关文章
- 雅礼集训 Day3 T2 u 解题报告
u 题目背景 \(\frac 14\) 遇到了一道水题,完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了一眼就切掉了这题,嘲讽了\(\frac 14\)一番就离开了. ...
- 雅礼集训 Day3 T3 w 解题报告
w 题目背景 \(\frac 14\)遇到了一道水题,双完全不会做,于是去请教小\(\text{D}\).小\(\text{D}\)看了\(0.607^2\)眼就切掉了这题,嘲讽了\(\frac 14 ...
- 雅礼集训 Day6 T2 Equation 解题报告
Equation 题目描述 有一棵\(n\)个点的以\(1\)为根的树,以及\(n\)个整数变量\(x_i\).树上\(i\)的父亲是\(f_i\),每条边\((i,f_i)\)有一个权值\(w_i\ ...
- 「雅礼集训 2017 Day2」解题报告
「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...
- 「雅礼集训 2017 Day1」 解题报告
「雅礼集训 2017 Day1」市场 挺神仙的一题.涉及区间加.区间除.区间最小值和区间和.虽然标算就是暴力,但是复杂度是有保证的. 我们知道如果线段树上的一个结点,\(max=min\) 或者 \( ...
- 雅礼集训 Day1 T3 画作 解题报告
画作 题目描述 小\(\mathrm{G}\)的喜欢作画,尤其喜欢仅使用黑白两色作画. 画作可以抽象成一个\(r\times c\)大小的\(01\)矩阵.现在小\(\mathrm{G}\)构思好了他 ...
- 雅礼集训 Day5 T3 题 解题报告
题 题目背景 由于出题人赶时间所以没办法编故事来作为背景. 题目描述 一开始有\(n\)个苹果,\(m\)个人依次来吃苹果,第\(i\)个人会尝试吃\(u_i\)或\(v_i\)号苹果,具体来说分三种 ...
- 雅礼集训 Day2 T3 联盟 解题报告
联盟 题目描述 \(\text{G}\) 国周边的 \(n\) 个小国家构成一个联盟以抵御 \(\text{G}\) 国入侵, 为互相支援,他们建立了\(n−1\) 条双向通路, 使得任意两个国家可以 ...
- 雅礼集训 Day7 T1 Equation 解题报告
Reverse 题目背景 小\(\text{G}\)有一个长度为\(n\)的\(01\)串\(T\),其中只有\(T_S=1\),其余位置都是\(0\).现在小\(\text{G}\)可以进行若干次以 ...
随机推荐
- Springcloud Eureka 启动失败:ERROR org.springframework.boot.SpringApplication - Application run failed
在测试Euruka作为服务注册中心的时候碰到了这个问题 [main] ERROR org.springframework.boot.SpringApplication - Application ru ...
- JS - CommonJS、AMD、CMD
CommonJS CommonJS是一种JS模块定义规范,它出现之初是为了解决JS天生没有模块管理的缺陷,它的终极目标是提供一个类似Python.Ruby和Java标准库.NodeJS的模块系统就是参 ...
- ubuntu16.06+vsftpd+nginx搭建图片服务器
安装vsftpd 注:以下指令都在root账户下操作 # apt安装vsftpd apt-get install vsftpd #启动vsftpd service vsftpd start #新建用户 ...
- hasOwnProperty自我理解
暂时不考虑ES6中symbol,hasOwnProperty()方法返回的是一个对象上是否包含一个指定属性,如果含有则返回true,如果没有则返回false. 和 in 运算符不同,该方法会忽略掉 ...
- HAN模型理解1
HAN 模型 最开始看这个模型是看的这个解释: RNN+Attention(HAN) 文本分类 阅读笔记 - 今天做作业没的文章 - 知乎 https://zhuanlan.zhihu.com/p/4 ...
- 17-比赛2 F - Fox And Two Dots (dfs)
Fox And Two Dots CodeForces - 510B ================================================================= ...
- 排序-InsertSort
数据结构之插入排序 参考----王道论坛2015年数据结构联考复习指南---- 算法稳定性:如果待排序表中有任意两个元素x1,x2相等,且排序前x1在x2的前面,使用某个排序算法之后,若x1仍然在x2 ...
- INSERT⋯ACCEPTING_DUPLICATE_KEYS
使用ACCEPTING DUPLICATE KEYS时,当插入时发现这条记录已存在时,那么这条记录将不会被insert,后续记录继续执行insert
- 財務会計関連(FI&CO)
[財務会計伝票]FB01: 登録FB02: 伝票変更FB09: 明細変更FB03: 照会FB04: 変更履歴照会FB08: 反対仕訳FB05: 消込転記FB50: G/L勘定伝票一般転記FB1S: 勘 ...
- laravel5.5artisan命令
目录 1. 简介 2. 编写命令 2.1 构建自己的命令 2.2 闭包命令 3. 定义输入期望 4.I/O 命令 5. 注册命令 6. 调用命令 1. 简介 Artisan 是 Laravel 自带的 ...