题解:CF1970E2 Trails (Medium)
前置知识
E1:dp。
E2:矩阵快速幂。
思路
暴力 dp
不难想到一个思路就是暴力 dp。
设
其中
原因很明显:如果没有限制,根据乘法原理,可以有
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long s[105],l[105],sum[105],dp[1005][105],ans;
int main(){
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)scanf("%lld",&s[i]);
for(int i=1;i<=m;i++){
scanf("%lld",&l[i]);
sum[i]=l[i]+s[i];
}
dp[0][1]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=1;k<=m;k++){
dp[i][j]=(dp[i][j]+((sum[k]*sum[j]-l[k]*l[j])%1000000007)*dp[i-1][k])%1000000007;
}
}
}
for(int i=1;i<=m;i++){
ans+=dp[n][i];
ans%=1000000007;
}
printf("%lld",ans%1000000007);
return 0;
}
时间复杂度
矩阵优化
显然对于 E2 上面做法是过不去的。
考虑一下:每次我们转移,对于一个确定的
因为矩阵有结合律,所以我们可以使用矩阵快速幂优化。
在矩阵优化题中,最重要的就是构造转移矩阵。这个题的转移矩阵就是
如果不理解,可以试着去手搓下面柿子的值:
就会得到:
所以这个矩阵是对的。
#include<bits/stdc++.h>
using namespace std;
struct matrix{
long long a[105][105];
};
int m;
long long n;
matrix operator *(matrix a,matrix b){
matrix c;
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
c.a[i][j]=0;
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=m;j++){
for(int k=1;k<=m;k++){
c.a[i][j]+=a.a[i][k]*b.a[k][j];
c.a[i][j]%=1000000007;
}
}
}
return c;
}
matrix qpow(matrix a,long long b){
matrix res;
for(int i=1;i<=m;i++){
res.a[1][i]=0;
}
res.a[1][1]=1;
while(b){
if(b&1)res=res*a;
a=a*a;
b>>=1;
}
return res;
}
long long s[105],l[105],sum[105],tot;
matrix a;
matrix ans;
int main(){
scanf("%d%lld",&m,&n);
for(int i=1;i<=m;i++)scanf("%lld",&s[i]);
for(int i=1;i<=m;i++){
scanf("%lld",&l[i]);
sum[i]=l[i]+s[i];
}
for(int i=1;i<=m;++i){
for(int j=1;j<=m;j++){
a.a[i][j]=(sum[i]*sum[j]-l[i]*l[j])%1000000007;
}
}
ans=qpow(a,n);
for(int i=1;i<=m;i++){
tot=(tot+ans.a[1][i])%1000000007;
}
printf("%lld",tot);
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】