P5241 序列(滚动数组+前缀和优化dp)

时间:2023-02-11 12:31:39

P5241 序列

挺神仙的一题

看看除了dp好像没什么其他办法了

想着怎么构个具体的图出来,然鹅不太现实。

于是我们想办法用几个参数来表示dp数组

加了几条边肯定要的吧,于是加个参数$i$表示已加了$i$条边

这显然是不够的。于是我们又想:强连通分量.....连通块.......

于是加个$j$表示还有$j$个强连通分量

于是dp数组为$f[i][j]$

这是我们发现一个问题,状态$f[i][j]$不一定是合法的。

那dp不就GG了吗

再次撕烤,我们发现每次加上的边无非就3种情况:

1.把2个强连通分量(或链)连成一条链

2.在某个强连通分量中瞎连(没啥用)

3.在1条链上的某点向回连,形成一个环,缩成一个新强连通分量(可以减少任意个强连通分量

我们设$k-1$条边(dp数组下标$k$为正数较好处理)投入到第3种情况

要生成剩下$j$个强连通的情况,我们最少投入$n-j$条边用于第1种情况

所以$n-j+(k-1)<=i$

我们又发现,要生成剩下$j$个强连通的情况,我们最多共投入的边数$i$是有限制的

最多情况就是1个块有$n-j+1$个点,剩下$j-1$个块只有1个点,蓝后大块每个点连$n-1$条边,小块互相之间弱连通

那么最大边数为$(n-j+1)*(n-1)+(j-2+j-3+j-4+...+1)=(n-j+1)*(n-1)+(j-1)*(j-2)/2$

所以$i<=(n-j+1)*(n-1)+(j-1)*(j-2)/2$

总结一下,即设$f[i][j][k]$表示到第$i$条边,有$j$个强连通分量,$k-1$条边向回连的方案数

限制条件:

$n-j+(k-1)<=i$

$i<=(n-j+1)*(n-1)+(j-1)*(j-2)/2$

转移:

$f[i][j][k]+=f[i-1][j][k]$(第2种情况)

$f[i][j][k]+=\sum_{h=j+1}^{n}f[i-1][h][k-1]$

显然是可以滚动数组+前缀和优化的辣

然鹅复杂度还是太高,主要因为k很麻烦

仔细观察k,发现

$n-j+(k-1)<=i$

$k<=i+j-n+1$

发现$i>=2n$时k总是合法的

于是我们就可以愉快地缩成2维辣

#include<iostream>
#include<cstdio>
#include<cstring>
#define rint register int
using namespace std;
inline int Min(int a,int b){return a<b?a:b;}
const int mod=1e9+;
inline int Md(int x){return x<mod?x:x-mod;}
#define N 405
int n,f[][N][N],sf[][N][N],g[][N],sg[N][N],lim[N],ans[N*N];
int main(){
scanf("%d",&n); int tn=Min(n*(n-),n<<),w=;
for(rint j=;j<=n;++j) lim[j]=(n-j+)*(n-)+(j-)*(j-)/;
f[][n][]=ans[]=;
for(rint j=;j<=n;++j) sf[][n][]=;
for(rint i=;i<=tn;++i,w^=){
for(rint j=;j<=n;++j)
for(rint k=;k<=n;++k)
f[w][j][k]=;
for(rint j=;j<=n;++j) if(lim[j]>=i)
for(rint k=;k<=n;++k) if(i-(k-)>=n-j)
f[w][j][k]=Md(f[w^][j][k]+sf[w^][j+][k-]);
for(rint j=n;j;--j)
for(rint k=;k<=n;++k){
sf[w][j][k]=Md(sf[w][j+][k]+f[w][j][k]);
ans[i]=Md(ans[i]+f[w][j][k]);
}
}w=;
for(rint j=;j<=n;++j)
for(rint k=;k<=n;++k)
g[][j]=Md(g[][j]+f[][j][k]);
for(rint j=n;j;--j) sg[][j]=Md(sg[][j+]+g[][j]);//降维
for(rint i=tn+;i<=n*(n-);++i,w^=){
for(rint j=;j<=n;++j) g[w][j]=;
for(rint j=;j<=n;++j) if(lim[j]>=i)
g[w][j]=Md(g[w^][j]+sg[w^][j+]);
for(rint j=n;j;--j){
sg[w][j]=Md(sg[w][j+]+g[w][j]);
ans[i]=Md(ans[i]+g[w][j]);
}
}
for(rint i=;i<=n*(n-);++i) printf("%d ",ans[i]);
return ;
}

P5241 序列(滚动数组+前缀和优化dp)的更多相关文章

  1. Codeforces 712 D&period; Memory and Scores &lpar;DP&plus;滚动数组&plus;前缀和优化&rpar;

    题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A ...

  2. LOJ 6089 小Y的背包计数问题 —— 前缀和优化DP

    题目:https://loj.ac/problem/6089 对于 i <= √n ,设 f[i][j] 表示前 i 种,体积为 j 的方案数,那么 f[i][j] = ∑(1 <= k ...

  3. bzoj2431&colon; &lbrack;HAOI2009&rsqb;逆序对数列&lpar;前缀和优化dp&rpar;

    2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 2312  Solved: 1330[Submit][Stat ...

  4. HDU-1024 Max Sum Plus Plus 动态规划 滚动数组和转移优化

    题目链接:https://cn.vjudge.net/problem/HDU-1024 题意 给n, m和一个序列,找m个不重叠子串,使这几个子串内元素和的和最大. n<=1e6 例:1 3 1 ...

  5. CF601C Kleof&&num;225&semi;š and the n-thlon&lpar;期望&plus;前缀和优化dp&rpar;

    传送门 解题思路 要求这个人的排名,我们可以先求出某个人比他排名靠前的概率,然后再乘上\(m-1\)即为答案.求某个人比他排名靠前可以用\(dp\),设\(f[i][j]\)表示前\(i\)场比赛某人 ...

  6. CDOJ 1307 ABCDE 前缀和优化dp

    ABCDE 题目连接: http://acm.uestc.edu.cn/#/problem/show/1307 Description Binary-coded decimal (BCD) is a ...

  7. bzoj 1044 &lbrack;HAOI2008&rsqb;木棍分割——前缀和优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1044 前缀和优化. 但开成long long会T.(仔细一看不用开long long) #i ...

  8. bzoj 3398 &lbrack;Usaco2009 Feb&rsqb;Bullcow 牡牛和牝牛——前缀和优化dp &sol; 排列组合

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 好简单呀.而且是自己想出来的. dp[ i ]表示最后一个牡牛在 i 的方案数. 当前 ...

  9. 5&period;19 省选模拟赛 小B的夏令营 概率 dp 前缀和优化dp

    LINK:小B的夏令营 这道题是以前从没见过的优化dp的方法 不过也在情理之中. 注意读题 千万不要像我这个sb一样 考完连题意都不知道是啥. 一个长方形 要求从上到下联通的概率. 容易发现 K天只是 ...

随机推荐

  1. phylogeny analysis

    Multiple Alignment: MUSCLE ProbCons T-Coffee ClustalW Alignment curation: Gblocks Remove positions w ...

  2. linux find命令

    Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数 ...

  3. Android 自定义View 三板斧之三——重写View来实现全新控件

    通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 本文来讨论最难的一种 ...

  4. Unity3D-Baked Lightmapping 示例学习

    首先,看一下摄像机的Rendering Paths http://game.ceeger.com/Manual/RenderingPaths.html 可以看出,对于灯光的渲染质量 Deferred ...

  5. Android第二天

    1.从看得见的活动入手 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ...

  6. maven私服搭建nexus&sol;windows&sol;linux(一)

    为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,还有就是公司内部开发的一些版本的jar包,如果没有私服需要一人拷贝一份然后再自己安 ...

  7. 洛谷P1993 小K的农场

    思路是差分约束+dfs版SPFA. 首先来思考差分约束的过程,将题目给出的式子进行转化: 农场a比农场b至少多种植了c个单位的作物, SPFA我们考虑跑最短路,那么要让SPFA中满足的式子就是if(d ...

  8. GMA Round 1 最大值

    传送门 最大值 求$f(x)=cos(x)+\sqrt{cos^2(x)-4\sqrt{3}cos(x)+4\sqrt{2}sin(x)+10}$的最大值.保留到小数点后3位. $f(x)+\sqrt ...

  9. 异步编程之使用yield from

    异步编程之使用yield from yield from 是 Python3.3 后新加的语言结构.yield from的主要功能是打开双向通道,把最外层的调用方法与最内层的子生成器连接起来.这两者就 ...

  10. jsoup对 HTML 文档的解析和操作

    本文手动转载自http://www.cnblogs.com/chenying99/archive/2013/01/04/2844615.html,仅根据个人需要对实用部分进行转载,详细请阅读原文. j ...