「模拟8.21」山洞(矩阵优化DP)
Posted wwb123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「模拟8.21」山洞(矩阵优化DP)相关的知识,希望对你有一定的参考价值。
暴力:
正解:
考虑循环矩阵,f[i][j]表示从i点到j点的方案数
我们发现n很小,我们预处理出n次的f[i][j]
然后在矩阵快速幂中,我们要从当前的f[i][j]*f[j][k]-->fir[i][j]
但是此时的循环为三层
我们考虑转移式子的意义在0-n次从i-j,在n+1到2×n转移至j
这样此时的j-k其实可以把他看作从0开始走j-k步本质上是一样的
然后还有一个特判,就不讲了
for(int j=0;j<n;++j) ff[now][j]=(ff[now][j]+ff[last][((j-i)+n)%n])%mod; if((((j-i)+n)%n)==(j+i)%n)continue; ff[now][j]=(ff[now][j]+ff[last][(j+i)%n])%mod;
代码
1 #include<bits/stdc++.h> 2 #define int long long 3 #define MAXN 4001 4 using namespace std; 5 int c[MAXN],f[MAXN],fir[MAXN]; 6 int n,m; 7 const int mod=1e9+7; 8 void cheng(int k) 9 10 memset(c,0,sizeof(c)); 11 if(k==1) 12 13 for(int i=0;i<n;++i) 14 15 for(int j=0;j<n;++j) 16 17 c[(i+j)%n]=(c[(i+j)%n]+f[j]*f[i]+mod)%mod; 18 //if(i*2==(j+i)%n)continue; 19 20 21 for(int i=0;i<n;++i)f[i]=c[i]%mod; 22 23 else 24 25 for(int i=0;i<n;++i) 26 27 for(int j=0;j<n;++j) 28 29 c[(i+j)%n]=(c[(i+j)%n]+fir[j]*f[i]+mod)%mod; 30 //if(i*2==((j+i)%n))continue; 31 32 33 for(int i=0;i<n;++i)fir[i]=c[i]%mod; 34 35 36 void poww(int y) 37 38 fir[0]=1ll; 39 while(y) 40 41 if(y&1ll)cheng(2ll); 42 cheng(1ll); 43 y>>=1ll; 44 45 46 int ff[4ll][MAXN];int g[MAXN]; 47 int now,last;int ans[MAXN]; 48 signed main() 49 50 //freopen("text.in","r",stdin); 51 //freopen("1.out","w",stdout); 52 scanf("%lld%lld",&n,&m); 53 int now=1;int last=0; 54 ff[0][0]=1; 55 for(int i=1;i<=n;++i) 56 57 if(i>1) 58 59 swap(now,last);memset(ff[now],0,sizeof(ff[now])); 60 61 for(int j=0;j<n;++j) 62 63 ff[now][j]=(ff[now][j]+ff[last][((j-i)+n)%n])%mod; 64 if((((j-i)+n)%n)==(j+i)%n)continue; 65 ff[now][j]=(ff[now][j]+ff[last][(j+i)%n])%mod; 66 67 if(i==m%n) 68 69 for(int j=0;j<n;++j) 70 71 g[j]=ff[now][j]%mod; 72 73 74 if(i==m) 75 76 printf("%lld\n",ff[now][0]); 77 return 0; 78 79 80 for(int i=0;i<n;++i) 81 82 f[i]=ff[now][i]%mod; 83 84 poww(m/n); 85 for(int i=0;i<n;++i) 86 87 for(int j=0;j<n;++j) 88 89 //if(i*2==((j+i)%n))continue; 90 ans[(i+j)%n]=(ans[(i+j)%n]+(g[i]*fir[j])%mod+mod)%mod; 91 92 93 if(m%n) 94 printf("%lld\n",ans[0]%mod); 95 else printf("%lld\n",fir[0]%mod); 96
以上是关于「模拟8.21」山洞(矩阵优化DP)的主要内容,如果未能解决你的问题,请参考以下文章