[CF1515E]Phoenix and Computers
Posted Tan_tan_tann
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1515E]Phoenix and Computers相关的知识,希望对你有一定的参考价值。
Phoenix and Computers
题解
忽然发现巨佬们的做法好像都跟我的不一样,就先写一下我的dp做法吧
湘妹的生成函数Or2
我们可以先定义 d p i , j dp_{i,j} dpi,j表示对于前 i i i个电脑,总共手动启动了 j j j个,且第 i i i个被手动启动时,前 i i i个都被启动的合法方案数。
由于
d
p
i
,
i
dp_{i,i}
dpi,i所对应的
d
p
dp
dp值会直接面对端点,不好转移,我们可以先将其预处理出来。
d
p
i
,
i
dp_{i,i}
dpi,i也就是表示前
i
i
i台电脑都被手动启动的方案数,由于只要任何时刻选取的电脑不是连续的,都会导致有电脑被自动启动,所以我们在启动第一台电脑后只能够在它的两边进行选择。
我们可以枚举第一台启动的电脑
j
j
j,那么剩下的启动方法就是个组合数
(
i
−
1
j
−
1
)
\\binom{i-1}{j-1}
(j−1i−1),所以有
d
p
i
,
i
=
∑
j
=
1
i
(
i
−
1
j
−
1
)
=
2
i
−
1
dp_{i,i}=\\sum_{j=1}^{i}\\binom{i-1}{j-1}=2^{i-1}
dpi,i=j=1∑i(j−1i−1)=2i−1
那么之后
d
p
i
,
j
dp_{i,j}
dpi,j的转移就比较好想了,我们可以枚举我们选了一个长度为
k
k
k的段一直选到
i
i
i,有转移方程式
d
p
i
,
j
=
∑
k
=
1
j
−
1
(
j
k
)
d
p
k
,
k
d
p
i
−
k
−
1
,
j
−
1
dp_{i,j}=\\sum_{k=1}^{j-1}\\binom{j}{k}dp_{k,k}dp_{i-k-1,j-1}
dpi,j=k=1∑j−1(kj)dpk,kdpi−k−1,j−1
由于新加入的段的选择与之前的选择间是互补干扰的,所以我们需要乘上
(
j
k
)
\\binom{j}{k}
(kj)
而新加入的段内部的选择方案为
d
p
k
,
k
dp_{k,k}
dpk,k,不同连续段之间必须有一个空格,且只能有一个空格,所以是对
d
p
i
−
k
−
1
,
j
−
1
dp_{i-k-1,j-1}
dpi−k−1,j−1进行转移。
最后答案为
∑
i
=
1
n
d
p
n
,
i
\\sum_{i=1}^{n}dp_{n,i}
∑i=1ndpn,i,最后一个点是必须被选择的,他不能被自动启动。
时间复杂度
O
(
n
3
)
O\\left(n^3\\right)
O(n3)。
其实我们还可以用卷积对原式进行优化,记
C
j
=
{
0
,
0
,
d
p
1
,
1
⋅
(
j
1
)
,
.
.
.
,
d
p
k
−
1
,
k
−
1
⋅
(
j
k
−
1
)
}
,
f
j
=
{
d
p
0
,
j
,
d
p
1
,
j
,
.
.
.
,
d
p
n
,
j
}
C_{j}=\\{0,0,dp_{1,1}\\cdot \\binom{j}{1},...,dp_{k-1,k-1}\\cdot\\binom{j}{k-1}\\},f_{j}=\\{dp_{0,j},dp_{1,j},...,dp_{n,j}\\}
Cj={0,0,dp1,1⋅(1j),...,dpk−1,k−1⋅(k−1j)},fj={dp0,j,dp1,j,...,dpn,j}
那么转移就变为了
f
j
=
C
j
f
j
−
1
f_{j}=C_{j}f_{j-1}
fj=Cjfj−1
时间复杂度
O
(
n
2
l
o
g
n
)
O\\left(n^2log\\,n\\right)
O(n2logn)
但由于
n
3
n^3
n3已经可以过了,笔者并没去打三模数NTT。
题解
#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define lowbit(x) (x&-x)
#define reg register
#define mp make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uint;
const int INF=0x7f7f7f7f;
const int jzm=233;
const int mo=998244353;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
x*=f;
}
int n,M,dp[405][405],C[405][405],ans;
int add(int x,int y){return x+y<M?x+y:x+y-M;}
int main(){
read(n);read(M);dp[0][0]=dp[1][1]=1;
for(int i=0;i<=n;i++)C[i][i]=C[i][0]=1;
for(int i=1;i<=n;i++)for(int j=1;j<i;j++)C[i][j]=add(C[i-1][j],C[i-1][j-1]);
for(int i=2;i<=n;i++)dp[i][i]=add(dp[i-1][i-1],dp[i-1][i-1]);
for(int i=2;i<=n;i++)
for(int k=1;k<i;k++){
for(int j=1;jCF1348E Phoenix and Berries(dp)
[CF1348D] Phoenix and Science - 贪心
[CF1348D] Phoenix and Science - 贪心