Link:

BZOJ 2817 传送门

Solution:

算是比较神的DP了吧,

首先这个绝对值处理起来很难受,肯定要想办法去掉

于是想到从小到大插入的方式,便不存在绝对值的问题

插入一个数只有5种情况,我们来分类讨论:

1.插入以后它两边都没有数。(权值$-2*i$,方案数$k+1-l$)

2.插入以后它两边都有数。(权值$2*i$,方案数$k-1$)

3.插入以后它的一边有数。(权值$0$,方案数$k*2-l$)

4.插入在边界上,且它旁边没有数。(权值$-i$,方案数$2-l$)

5.插入在边界上,且它旁边有数。(权值$i$,方案数$2-l$)

可以发现每种情况产生的权值都可以确定,且方案数也可以确定,于是想到便能使用DP转移

设$f[i][j][k][l]$表示当前插入$i$个数,权值为$j$,序列被分为$k$段,序列两端状态为$l$时的方案数

$l$表示序列两端是有0/1/2个数

接下来就是巨恶心的高精度处理了:

手写高精度速度肯定是不够的,

于是只能用正式OI不给用的黑科技__float128了,(讲道理是不能用的,但不管A了就行)

一篇介绍的文章

能保留小数点后32位,整数位能表示到1e4392?超乎我的想象

(注意输出时要手动处理一下)

但这还不够,$k<=8$时还是TLE,

于是还要将输入分类,如果$k<=8$用double,否则才用__float128

学会使用Template和namespace来进行不同处理

Code:

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. #define ll long long
  5. #define RG register
  6. const int M=4500;
  7.  
  8. namespace db{double f[2][2*M+1][101][3];}
  9. namespace f128{__float128 f[2][2*M+1][101][3];}
  10. int n,m,k;
  11.  
  12. template<class T> inline void print(T res)
  13. {
  14. printf("%d.",(int)res); //逐位输出
  15. while(k--)
  16. {
  17. res=(res-(int)res)*10;
  18. if(!k) res+=0.5;
  19. printf("%d",(int)res);
  20. }
  21. }
  22.  
  23. template<class T> inline void solve(T f[2][2*M+1][101][3])
  24. {
  25. f[1][M-1][1][1]=2;f[1][M-2][1][0]=1;f[0][M][1][2]=1;
  26. for(RG int i=2,cur=0,pre=1;i<=n;++i,pre=cur,cur^=1)
  27. {
  28. memset(f[cur],0,sizeof(f[cur]));
  29. for(RG int j=0;j<=2*M;++j)
  30. for(RG int k=1;k<=n-1;++k)
  31. for(RG int l=0;l<=2;++l)
  32. {
  33. if(!f[pre][j][k][l]) continue;
  34. if(j+2*i<=2*M) f[cur][j+2*i][k-1][l]+=f[pre][j][k][l]*(k-1);
  35. if(j>=2*i) f[cur][j-2*i][k+1][l]+=f[pre][j][k][l]*(k+1-l);
  36. f[cur][j][k][l]+=f[pre][j][k][l]*(k*2-l);
  37. if(l<2)
  38. {
  39. if(j+i<=2*M) f[cur][j+i][k][l+1]+=f[pre][j][k][l]*(2-l);
  40. if(j>=i) f[cur][j-i][k+1][l+1]+=f[pre][j][k][l]*(2-l);
  41. }
  42. }
  43. }
  44.  
  45. T res=0;
  46. for(RG int i=M+m;i<=2*M;++i) res+=f[n&1][i][1][2];
  47. for(RG int i=2;i<=n;++i) res/=i;
  48. print(res);
  49. }
  50.  
  51. int main()
  52. {
  53. cin >> n >> m >> k;
  54. if(k<=8) solve(db::f);
  55. else solve(f128::f);
  56. return 0;
  57. }

Review:

1、通过排序的预处理规避绝对值运算

2、DP时对边界条件加一个特殊状态

3、对__float128的使用(输出要特殊处理)

4、使用Template+namespace等方法提高代码重用性

[BZOJ 2817] 波浪的更多相关文章

  1. bzoj2817[ZJOI2012]波浪

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=2817 波浪 [问题描述] 阿米巴和小强是好朋友. 阿米巴和小强在大海旁边看海水的波涛.小 ...

  2. 【BZOJ2817】[ZJOI2012]波浪(动态规划)

    [BZOJ2817][ZJOI2012]波浪(动态规划) 题面 BZOJ 洛谷 题解 首先这个差值最大也就是\(n^2\)级别的. 那么这样子就可以压进状态啦. 我们把这个操作看成一个个加数的操作,按 ...

  3. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  4. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  5. HTML5 Canvas玩转酷炫大波浪进度图

    如上图所见,本文就是要实现上面那种效果. 由于最近AlloyTouch要写一个下拉刷新的酷炫loading效果.所以首选大波浪进度图. 首先要封装一下大波浪图片进度组件.基本的原理是利用Canvas绘 ...

  6. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  7. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  8. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  9. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

随机推荐

  1. git使用笔记(一)入门

    By francis_hao    Nov 17,2016 本来是想把git的使用笔记写在一个文件里,但是越写越长,最后也不得不分开了.这样也好,每一篇一个侧重,可以写的详细一点.   初学乍练 在l ...

  2. 用boost::lexical_cast进行数值转换

    在STL库中,我们可以通过stringstream来实现字符串和数字间的转换: int i = 0;    stringstream ss; ss << "123";  ...

  3. 迅雷Bolt的ClipSubBindBitmap函数特别说明

    因为在工作中基于迅雷Bolt开发的是IM产品,需要实现自定义用户头像的功能. 但Bolt中对图像的默认拉伸锯齿效果非常明显,所以自己实现了图像拉伸函数,代码已共享,具体可查看:<迅雷Bolt图像 ...

  4. PowerDesigner使用教程(转)

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...

  5. 关于MyBatis的collection集合中只能取到一条数据的问题

    问题:在涉及多表查询的时候,使用collection元素来映射集合属性时,出现了只能查询到一条数据的情况,但用sql语句在数据库中查询会有多条记录. 解决:如果两表联查,主表和明细表的主键都是id的话 ...

  6. 有关javamelody的配置

    一:前沿 在这里我学到了怎么来使用开源的东西,也第一次去接触有关性能方面检测的开源框架,javamelody是性能检测的,刚刚看的时候我什么都不知道的,但是自己接触了,才知道一点大概思路吧.下面来记载 ...

  7. OpenStack搭建glance

    1.创建数据库 mysql -uroot -p create database glance; grant all privileges on glance.* to glance@'localhos ...

  8. bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑——倍增floyd

    Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力跑的地点 自然是在牧场中现有的T(2 <= T < ...

  9. openstack中region、az、host aggregate、cell 概念

    1. region 更像是一个地理上的概念,每个region有自己独立的endpoint,regions之间完全隔离,但是多个regions之间共享同一个keystone和dashboard.(注:目 ...

  10. VC6.0显示行号的插件

    VC6.0显示行号的插件,很好很强大的显行号插件,使用VC编程的朋友再也不用烦恼VC6.0没有行号的编程环境了. VC显示行号插件使用说明:1. 如果你的VC安装在C盘,请拷贝文件VC6LineNum ...