首先这道题用到的3个新关键字大概讲一下:

(我刚学会仅仅会瞎搞做题,欢迎大神补充)

static:声明一个变量并清空。(不知道用不用时间,求解答)

具体用法:static 变量类型 变量名。如:static int a[1005];

百度了一下。static在第一次声明时是0,但是下次进入这个函数时它不会再次清空而是保持原状。

讲的不错的博客

class:和其它的变量类型差不多,只不过class存的是一个变量类型,常与template连用

具体用法:class 变量名。不能赋值。如:class s=bool;是编译不过的,但是class s;可以

template:特殊的函数传参方法,可以传class类型的变量(至少我是这么理解的)

具体用法:template<变量类型 变量名,变量类型 变量名...>函数类型 函数名(函数传参){}

在函数定义时前面加<>,里面加上任意多个变量类型及变量名,和在小括号里的传参类似。

如:template<class nd,int N,int M>void work(int p){nd a[1005];return;}

然后这题虽然看了题解发了std之后AC一片一片的,但是其实真的没有那么好想。

首先dp定义是dp[i][j][k][l]表示已经填了i位,目前累计的“赤壁之意”为j,已经分成了k段,序列的端点已经被用上了l个。

第一维可滚动。数组大小为2*7500*50*3。空间可接受。100*7500*50*3时间可接受。(7500怎么来的等会讲)

这里的段的内部次序已经确定,段之间的先后关系也已经确定,但是它们在原序列上的具体位置和间隔距离并不确定。

假设目前的状态dp[i][j][k][l]=DP,i从0开始枚举,从小往大填。

dp[i&1^1][j-2-i*2][k+1][l]+=DP*(k+1-l),表示你新开了一个段只有i+1这个数,在目前已有k个段的情况下一共有k+1种位置可插入,插入后“赤壁之意“累加-2i-2

因为你这个数左右两边都没有值,以后填的值都比这个值大,所以abs就是两边的和分别减去i+1,所以填i+1的贡献就是-2i-2。

但是如果已经有一个端点确定了,那么这个新段就不能加在最前面了,两个端点都确定的话同理,所以可选择位置要减去l。

dp[i&1^1][j][k][l]+=DP*(2*k-l),表示你在某一个段的一个端点上加上了i+1这个数,k个段每个都有2个端点,但是整个序列已经确定的端点上不能加数,所以就是2k-l。

这样的贡献是0,对于已经填上的数它一定比i+1小那么会产生i+1的贡献,另一端还没有填的一定比它大会产生-i-1的贡献抵消了。

dp[i&1^1][j+2+2*i][k-1][l]+=DP*( k-1 ),表示你把两个段合并,k个段之间有k-1个位置来合并。合并操作并不受端点是否已经确定的影响。

dp[i&1^1][j-1-i][k+1][l+1]+=DP*( 2-l ),表示在端点处新建一个段。

dp[i&1^1][j+1+i][k][l+1]+=DP*( 2-l ),表示把一个段的端点延伸并设为整个序列的端点。

至于7500是怎么来的,就是最后的答案不会超过n(n+1)/2这比较显然,开大更好,大约是5000。

然而上来一直建新段的话会导致过程中你的积分是负的,最多u会负n(n+1)/4,大约是-2500。

和起来就是7500。对于float128的n=50的测试点相应的小4倍。

Lockey提出了倒着扫回去先放大数,这样的话就不用担心过程中分数会出负数了。

 #include<cstdio>
#include<cstring>
__float128 ans;int n,m,k;
#define DP dp[i&1][j][k][l]
int floor(__float128 x){
for(int i=;i>=;--i)if(x>=i)return i;
}
void print__float128(__float128 x,int ws){
int sta[];sta[]=;
for(int i=;i<=ws;++i)x*=,sta[i]=floor(x),x-=floor(x);
x*=;if(floor(x)>=)sta[k]++;
for(int i=ws;i;--i)if(sta[i]==)sta[i]=,sta[i-]++;
printf("%d.",sta[]);
for(int i=;i<=ws;++i)printf("%d",sta[i]);
puts("");
}
int main(){
scanf("%d%d%d",&n,&m,&k);
if(k<=){
static double dp[][][][];
#define $ 12345
dp[][$][][]=;
for(int i=;i<n;++i){
std::memset(dp[i&^],,sizeof dp[]);
for(int j=;j<=$+(n+)*n/;++j)for(int k=;k<=;++k)for(int l=;l<=;++l)if(DP>=0.998){
dp[i&^][j--i*][k+][ l ]+=DP*(k+-l);
dp[i&^][ j ][ k ][ l ]+=DP*(*k-l);
dp[i&^][j++*i][k-][ l ]+=DP*(k-);
dp[i&^][ j--i ][k+][l+]+=DP*(-l);
dp[i&^][ j++i ][ k ][l+]+=DP*(-l);
}
}
for(int j=m+$;j<=$+(n+)*n/;++j)ans+=dp[n&][j][][];
}else{
static __float128 dp[][][][];
#define $ 3000
dp[][$][][]=;
for(int i=;i<n;++i){
std::memset(dp[i&^],,sizeof dp[]);
for(int j=;j<=$+(n+)*n/;++j)for(int k=;k<=;++k)for(int l=;l<=;++l)if(DP>=0.998){
dp[i&^][j--i*][k+][ l ]+=DP*(k+-l);
dp[i&^][ j ][ k ][ l ]+=DP*(*k-l);
dp[i&^][j++*i][k-][ l ]+=DP*(k-);
dp[i&^][ j--i ][k+][l+]+=DP*(-l);
dp[i&^][ j++i ][ k ][l+]+=DP*(-l);
}
}
for(int j=m+$;j<=$+(n+)*n/;++j)ans+=dp[n&][j][][];
}
for(int i=;i<=n;++i)ans/=i;
print__float128(ans,k);
}

未用tmeplate。1.6k

 #include<cstdio>
__float128 ans;int n,m,k;
#define DP dp[i&1][j][k][l]
int floor(__float128 x){for(int i=;i>=;--i)if(x>=i)return i;}
void print__float128(__float128 x,int ws){
int sta[];sta[]=;
for(int i=;i<=ws;++i)x*=,sta[i]=floor(x),x-=floor(x);
if(floor(x*)>=)sta[k]++;
for(int i=ws;i;--i)if(sta[i]==)sta[i]=,sta[i-]++;
printf("%d.",sta[]);for(int i=;i<=ws;++i)printf("%d",sta[i]);
}
int P(int a){return a<?:a;}
template<class nd,int N,int M>void work(){
static nd dp[][N][][];
dp[][M][][]=;
for(int i=;i<n;++i)for(int j=;j<=M+(n+)*n/;++j)for(int k=i?:;k<=;++k)for(int l=;l<=;++l)if(DP>=0.998)
dp[i&^][P(j--i*)][k+][ l ]+=DP*(k+-l),
dp[i&^][ j ][ k ][ l ]+=DP*(*k-l),
dp[i&^][ j++*i ][k-][ l ]+=DP*( k- ),
dp[i&^][ P(j--i) ][k+][l+]+=DP*( -l ),
dp[i&^][ j++i ][ k ][l+]+=DP*( -l ),
DP=;
for(int j=m+M;j<=M+(n+)*n/;++j)ans+=dp[n&][j][][];
for(int i=;i<=n;++i)ans/=i;
print__float128(ans,k);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
if(k<=)work<double,,>();else work<__float128,,>();
}

加template,1.1k

 #include<cstdio>
__float128 ans;int n,m,k;
#define DP dp[i&1][j][k][l]
int floor(__float128 x){for(int i=;i>=;--i)if(x>=i)return i;}
void print__float128(__float128 x,int ws){
int sta[];sta[]=;
for(int i=;i<=ws;++i)x*=,sta[i]=floor(x),x-=floor(x);
if(floor(x*)>=)sta[k]++;
for(int i=ws;i;--i)if(sta[i]==)sta[i]=,sta[i-]++;
printf("%d.",sta[]);for(int i=;i<=ws;++i)printf("%d",sta[i]);
}
template<class nd>void work(){
static nd dp[][][][];
dp[n&][][][]=;
for(int i=n;i;--i)for(int j=;j<=(n+)*n*/;++j)for(int k=;k<=;++k)for(int l=;l<=;++l)if(DP>=0.998){
dp[i&^][j+*i][k+][ l ]+=DP*(k+-l);
dp[i&^][ j ][ k ][ l ]+=DP*(*k-l);
if(k&&j>=*i)dp[i&^][j-*i][k-][ l ]+=DP*( k- );
dp[i&^][ j+i ][k+][l+]+=DP*( -l );
if(j>=i) dp[i&^][ j-i ][ k ][l+]+=DP*( -l );
DP=;
}
for(int j=m;j<=(n+)*n/;++j)ans+=dp[][j][][];
for(int i=;i<=n;++i)ans/=i;
print__float128(ans,k);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
if(k<=)work<double>();else work<__float128>();
}

加Lockey优化,1.0k

时间复杂度倒是差不多。

赤壁情:dp的更多相关文章

  1. [CSP-S模拟测试]:赤壁情(DP)

    前赤壁赋 壬戌之秋,七月既望,苏子与客泛舟游于赤壁之下.清风徐来,水波不兴.举酒属客,诵明月之诗,歌窈窕之章.少焉,月出于东山之上,徘徊于斗牛之间.白露横江,水光接天.纵一苇之所如,凌万顷之茫然.浩浩 ...

  2. [NOIP模拟33]反思+题解

    又考了一次降智题…… 拿到T1秒出正解(可能是因为我高考数学数列学的海星?),分解质因数以后用等比数列求和计算每个因子的贡献.但是当时太过兴奋把最后的$ans \times =$打成了$ans +=$ ...

  3. HZOI20190829模拟33题解

    题面:https://www.cnblogs.com/Juve/articles/11436771.html A:春思 我们对a分解质因数,则$a=\prod\limits_p^{p|a}p^k$ 所 ...

  4. [NOIP2016]换教室 D1 T3 Floyed+期望DP

    [NOIP2016]换教室 D1 T3 Description 对于刚上大学的牛牛来说, 他面临的第一个问题是如何根据实际情况中情合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第 ...

  5. HDU1011 树形DP

    Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  7. Day1:T3 bfs T4 树形DP

    T3:BFS 回看了一下Day1的T3...感觉裸裸的BFS,自己当时居然没有看出来... 同时用上升和下降两种状态bfs即可 这一题还要注意一个细节的地方,就是题目要求的是求往返的最优解 k=min ...

  8. USACO奶牛博览会(DP)

    Description 奶牛想证明他们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N头奶牛进行了面试,确定了每头奶牛的智商和情商. 贝西有权选择让哪些奶牛参加展览.由于负的智商或情商会造成 ...

  9. 10-19 dp专练

    dp专练,终于克服了一次自己对dp的恐惧,磕出来一道题. 得分情况: T1:0 T2:0 T3:0 emmmm,磕出来的题是T2,但是因为初始化和int long long的原因爆零了 T1:n只狼排 ...

随机推荐

  1. [Android Studio] 2019年Android Studio配置指北

    Android Studio是我学习Android开发路上的第一块绊脚石,新建一个项目,一行代码没动,直接编译不起来,我太难了,所以本文叫指北 本文讲解在9102年如何在国内网络不通畅的情况下流畅的使 ...

  2. HTML块元素与内联元素嵌套规则

    HTML存在许多种类型的标签,有的标签下面只允许特定的标签存在,这就叫HTML嵌套规则.不按HTML嵌套规则写,浏览器就不会正确解析,会将不符合嵌套规则的节点放到目标节点的下面,或者变成纯文本.关于H ...

  3. e课表项目第二次冲刺周期第一天

    昨天干了什么? 昨天与我们小组的成员商量了一个重大的决定,由于我们第一次冲刺周期的成果,就是我们决定我们要转型发展. 今天干了什么? 查阅相关的资料,我们正式决定要做一款学习的课程表APP,把简易作为 ...

  4. Java 语言特点

    引入<Java核心技术:Ⅰ> 1. 简单性 Java 语法是 C++ 语法的一个“ 纯净” 版本.这里没有头文件. 指针运算(甚至指 针语法).结构. 联合.操作符重载. 虚基类等.如果你 ...

  5. eclipse常用快捷键即项目操作

    快捷键: 1.代码提示:Alt+/ 2.撤销上一步操作:Ctrl+z:取消撤销:Ctrl+y: 3.如何注销一整段代码?☞▲第一种注释方法是每行代码前加//:先选中,然后按Ctrl+/:取消注销方法一 ...

  6. 手把手教你搭建HEXO免费博客

    一.环境搭建 node安装 百度搜索node,进入官网.下载稳定版: 下载好后直接打开安装 我这里将其安装在D盘(可以自己选择安装位置) 可以看到安装包中已经自带npm包管理工具 等待安装完成后,WI ...

  7. 日志::spdlog

    https://github.com/gabime/spdlog git clone https://github.com/gabime/spdlog.git cd spdlog && ...

  8. 测试中常用sql

    1.增删改查 2.同一服务器下,要从一个数据库复制某张表到另一个数据库 create table test.sf_audit_plan as select * from v3_0_sf_full.sf ...

  9. window下设置定时任务及基本配置

    ### window下设置定时任务及基本配置 轉載請註明出處: https://www.cnblogs.com/funnyzpc/p/11746439.html |****************** ...

  10. Spring Cloud Alibaba 使用nacos 注册中心

    ### 背景 上一文我们讲到了如何去搭建注册中心,这一次我们讲述如何使用nacos作为注册中心 ### spring-cloud-alibaba-basis 创建基础依赖 首先我们创建一个spring ...