清橙A1202 bzoj2201 bsoj4074

试题来源

  2010中国国家集训队命题答辩

问题描述

  小A喜欢收集宝物。一天他得到了一个圆环,圆环上有N颗彩色宝石,闪闪发光。小A很爱惜这个圆环,天天把它带在身边。
  一天,小A突然发现圆环上宝石的颜色是会变化的。他十分惊讶,仔细观察这个圆环后发现,圆环上宝石的颜色每天变化一次,而且每颗宝石的颜色都等概率地为特定的M种颜色之一。小A发现了这个秘密后,对圆环更是爱不释手,时时刻刻都在研究。
  又经过了一段时间,小A发现因为圆环上宝石的颜色不断变化,圆环有时会显得比其他时候更美丽。为了方便比较,小A这样定义圆环的“美观程度”:
  设圆环上相同颜色的宝石构成的连续段长度分别为a1, a2, ..., an
  定义圆环的“美观程度” \(R = \prod_{i=1}^{n} a_i\) 。以图一给出的圆环为例,有a1 = 3, a2 = 2, a3 = 1,故R = 6。
  现在小A想知道,在上述前提下,圆环的“美观程度”的期望值E(R)是多少。因为如果知道了E(R),他就可以判断每天变化出的新圆环是否比一般情况更美丽。
  说明:“美观程度”的期望值即为对每种可能的圆环状态的“美观程度”与其出现概率的乘积进行求和所得的值。

输入格式

  输入仅有一行,该行给出依次两个正整数N, M,分别表示宝石的个数和宝石在变化时可能变成的颜色种类数。

输出格式

  输出应仅有一行,该行给出一个实数E(R),表示圆环的“美观程度”的期望值。

样例输入

3 2

样例输出

2.25

样例输入

200 1

样例输出

200

数据规模和约定

  20%的数据满足1 ≤ N, M ≤ 8;
  50%的数据满足1 ≤ N, M ≤ 25;
  100%的数据满足1 ≤ N ≤ 200, 1 ≤ M ≤10^9。

先看看这篇官方题解的问题\(A\),了解一下经典的圆环染色问题

——《彩色圆环(circle)》命题报告,吴佳俊

题外话:其实还可以更优,用矩阵快速幂可以优化,也可以特征根推出通项公式,这里不展开讨论了

我们从中获取了一种处理环上dp的思路,即增设一维来维护首尾是否相同

先来看链的情况

设\(f[i]\)表示考虑到第\(i\)位时的期望美观度,显然有
\[
f[i]=\sum_{0 \le j < i} f[j]*(i-j)*P[i-j]*(M-1)
\]
其中\(P[i]\)表示连续选\(i\)个相同一种颜色的概率
\[
P[i] = M^{-i}\\
\]
那么现在用圆环染色的思路来试着写环的dp式

\(f[i][0/1]\)表示要决定的序列的前面(0位)已经确定了一种颜色,考虑到该序列第\(i\)位,且要求该位颜色与(1)/不与(0)0位颜色相同时,期望的美观度(许多题解对\(f\)的定义描述并不准确,实际上这里与圆环染色设置的状态有一点不同,就是实际上开头的颜色是不包含在我们要dp的那一段链中的。这关系到后面计算答案的正确性)
\[
f[i][0] = \sum_{0 \le j < i} f[j][0]*(i-j)*P[i-j]*(m-2) + f[j][1]*(i-j)*P[i-j]*(m-1)\\
f[i][1] = \sum_{0 \le j < i} f[j][0]*(i-j)*P[i-j]
\]
考虑如何求答案。考虑将首尾相接的那个颜色块的贡献单独拎出来计算。枚举首尾相接颜色块两端加起来的总长度\(x\),则总共有\(x\)种分割首尾的方案,每种方案有\(M\)个颜色可以选择,每个方案贡献为\(x\),剩下的部分就可以用\(f\)来表示了

\(x=N\)时要特判
\[
Ans = P[N]*N*M + \sum_{1 \le x < N} x*x*P[x]*M*f[n-x][0]
\]

\(O(n^2)\)的代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<queue>
#include<vector>
using namespace std;
typedef long double ldb;
typedef long long ll;

const ll MXN=1005;
ll N,M;
ldb f[MXN][2];
ldb P[MXN];
int main(){
    cin>>N>>M;
    P[0]=1;for(ll i=1;i<=N;i++) P[i]=P[i-1]/M;
    //f数组开两维,实际上是在与位于0位的虚拟颜色斗智斗勇,即f[i][0/1]表示:某一种颜色在序列的最前方(0位),最后一位是否与该颜色相同,美观程度的期望
    //这样设状态就给后面的答案计算提供了便捷
    f[0][0]=0;f[0][1]=1;//f[0][0]置0,是因为不能让f[i][1]直接从0转移
    for(ll i=1;i<=N;i++){
        f[i][0]=f[i][1]=0;
        for(ll j=0;j<i;j++){//可以从0转移,给了只有一个块转移的机会
            f[i][0]+=f[j][0]*(i-j)*P[i-j]*(M-2)
                    +f[j][1]*(i-j)*P[i-j]*(M-1);
            f[i][1]+=f[j][0]*(i-j)*P[i-j];
        }
    }
    ldb ans=N*P[N]*M;
    for(ll x=1;x<N;x++)
        ans+=x*x*P[x]*M*f[N-x][0];//一个x是贡献,一个x是分割开头和结尾的方式数,f[N-x][0]则充当了中间部分
    printf("%.5Lf",ans);
    return 0;
}

我们发现推出的dp方程有一部分是与\(j\)无关的。将它们提出来,维护剩下的只与\(j\)有关的前缀和,复杂度即可降至\(O(N)\)

前缀和优化后\(O(n)\)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<queue>
#include<vector>
using namespace std;
typedef long double ldb;
typedef long long ll;

const ll MXN=1000005;
ll N,M;
ldb f[MXN][2];
ldb powM[MXN];//M^i
int main(){
    cin>>N>>M;
    powM[0]=1;for(ll i=1;i<=N;i++) powM[i]=powM[i-1]*M;

    f[0][0]=0;f[0][1]=1;
    ldb s_01=0,s_0j=0;
    ldb s_11=1,s_1j=0;
    for(ll i=1;i<=N;i++){
        f[i][0] = s_01*(M-2)*i/powM[i] + s_0j*(M-2)/powM[i]
                + s_11*(M-1)*i/powM[i] + s_1j*(M-1)/powM[i];
        f[i][1] = s_01      *i/powM[i] + s_0j      /powM[i];

        s_01 += f[i][0]*powM[i];
        s_0j += f[i][0]*powM[i]*i;
        s_11 += f[i][1]*powM[i];
        s_1j += f[i][1]*powM[i]*i;
    }
    ldb ans=N/powM[N]*M;
    for(ll x=1;x<N;x++)
        ans+=x*x/powM[x]*M*f[N-x][0];
    printf("%.5Lf",ans);
    return 0;
}

实际上是会炸精度的,懒得管了:p

从《彩色圆环》一题探讨一类环上dp的解法的更多相关文章

  1. tyvj 1342 教主泡嫦娥 环上DP

    342 教主泡嫦娥 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 2012年12月21日下午3点14分35秒,全世界各国的总统以及领导人都已经汇聚在中国的方 ...

  2. [期望DP][纪中]【2010集训队出题】彩色圆环

    彩色圆环 感谢名单 十分感谢 JA_Ma 为我讲解了 \(T1\) 的 期望DP 的思想和推论. 十分感谢 SSL_LYF 为我解答了 \(T1\) 的 期望DP 的概率的大小问题. 十分感谢 SSL ...

  3. 关于一类容斥原理设计 dp 状态的探讨

    写在前面 为什么要写?因为自己学不明白希望日后能掌握. 大体思路大概是 设计一个容斥的方案,并使其贡献可以便于计算. 得出 dp 状态,然后优化以得出答案. 下列所有类似 \([l,r]\) 这样的都 ...

  4. [提升性选讲] 树形DP进阶:一类非线性的树形DP问题(例题 BZOJ4403 BZOJ3167)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7337179.html 树形DP是一种在树上进行的DP相对比较难的DP题型.由于状态的定义多种多样,因此解法也五 ...

  5. [Hdu-5155] Harry And Magic Box[思维题+容斥,计数Dp]

    Online Judge:Hdu5155 Label:思维题+容斥,计数Dp 题面: 题目描述 给定一个大小为\(N*M\)的神奇盒子,里面每行每列都至少有一个钻石,问可行的排列方案数.由于答案较大, ...

  6. Slope Trick:解决一类凸代价函数DP优化

    [前言] 在补Codeforce的DP时遇到一个比较新颖的题,然后在知乎上刚好 hycc 桑也写了这道题的相关题解,这里是作为学习并引用博客的部分内容 这道题追根溯源发现2016年这个算法已经在API ...

  7. Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量

    D. Directed Roads   ZS the Coder and Chris the Baboon has explored Udayland for quite some time. The ...

  8. HDU 4443 带环树形dp

    思路:如果只有一棵树这个问题很好解决,dp一次,然后再dfs一次往下压求答案就好啦,带环的话,考虑到环上的点不是 很多,可以暴力处理出环上的信息,然后最后一次dfs往下压求答案就好啦.细节比较多. # ...

  9. LightOJ 1074 Extended Traffic(spfa+dfs标记负环上的点)

    题目链接:https://cn.vjudge.net/contest/189021#problem/O 题目大意:有n个站点,每个站点都有一个busyness,从站点A到站点B的花费为(busynes ...

随机推荐

  1. Win10如何快速截屏

    Win10不用QQ,如何快速截屏? 年轻的时候想截图总是需要把QQ打开,但是直到我遇到了一种尴尬的场景:就是需要我把鼠标放着标签上,才会有下一步内容出现,这就很难搞. 经过查找资料,做出一些总结. 第 ...

  2. c#关于数据和方法在不同类中的引用-xdd

    关于数据和方法在不同类中的引用 using System; using System.Collections.Generic; using System.Linq; using System.Text ...

  3. JVM学习笔记(1)--运行时数据区域

    运行时数据区域 相对于c,c++.程序设计时,java并不需要手动释放或者创建内存用于存放程序,这的确使得java开发变得容易和轻松,一旦有一天出现了内存泄漏或者内存溢出的问题,如果不了解JVM虚拟机 ...

  4. PHP+Redis实现延迟任务,实现自动取消与完成订单

    简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) : (A)业务场景: 1.当一个业务触发以后需要启动一个定时任务,在指定时间内再去执行一个任务( ...

  5. Redis系列(四):Redis持久化和主从复制原理

    一.持久化 所谓的持久化就是把内存中的数据写到磁盘中去,防止服务宕机后内存数据丢失.Redis4.0之前提供了两种持久化方式:RDB(默认) 和AOF,Redis4.x之后新增了一种混合持久化(本文所 ...

  6. PHP如何获取视频总时长与码率等信息

    利用PHP中的FFmpeg读取视频播放时长与码率等信息   function getVideoInfo($file) {    define('FFMPEG_PATH', '/usr/local/ff ...

  7. input 输入框 只能输入数字、字母、汉字等

    1.文本框只能输入数字代码(小数点也不能输入) <input onkeyup="this.value=this.value.replace(/\D/g,'')" onafte ...

  8. 【LiteOS】STM32F103-LiteOS移植教程(详细篇)【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...

  9. 使用app测试Modelarts在线服务

    1. 基础准备 本demo代码已上传github地址为 https://github.com/zxzxzxygithub/hwmodelartdemo clone下来之后导入android studi ...

  10. Docker数据挂载

    Docker数据管理 在容器中管理数据主要有两种方式: 数据卷(Volumes) 挂载主机目录(Bind mounts) 数据卷 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很 ...