hdu 2294 Pendant(矩阵乘法)
2014-02-23 13:13
417 查看
题意:求长度为1~N的项链,用必须用k种珍珠组成的方案数。
思路:首先可以想想dp,可以推出dp方程,用dp[i][j]表示长度为i的项链用j种珍珠的方案数。则dp[i][j]=dp[i-1][j]*j+dp[i-1][j-1]*(k-j+1),由于N非常大,因此直接dp是不现实的,因此我们想到了用矩阵乘法加速运算,矩阵A的元素分别是长度为n时用j种的方案数,因此要求的就为A+A^2+A^3……+A^n。可能我构造矩阵的方式有些奇怪?感觉和网上的思路都一样,但是矩阵构造方式看不懂。。。。
代码:
题意:求长度为1~N的项链,用必须用k种珍珠组成的方案数。
思路:首先可以想想dp,可以推出dp方程,用dp[i][j]表示长度为i的项链用j种珍珠的方案数。则dp[i][j]=dp[i-1][j]*j+dp[i-1][j-1]*(k-j+1),由于N非常大,因此直接dp是不现实的,因此我们想到了用矩阵乘法加速运算,矩阵A的元素分别是长度为n时用j种的方案数,因此要求的就为A+A^2+A^3……+A^n。可能我构造矩阵的方式有些奇怪?感觉和网上的思路都一样,但是矩阵构造方式看不懂。。。。
代码:
#include <iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; typedef long long ll; const int maxn=33; const ll mod=1234567891; struct Matrix { ll mat[maxn][maxn]; int n; Matrix(){}; Matrix(int nn){n=nn;} void Init() { for(int i=0;i<n;++i) for(int j=0;j<n;++j) mat[i][j]=(i==j); } void clear(){memset(mat,0,sizeof(mat));} }; Matrix operator *(const Matrix &a,const Matrix &b) { Matrix c(a.n);c.clear(); for(int k=0;k<c.n;++k) for(int i=0;i<c.n;++i) for(int j=0;j<c.n;++j) c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod; return c; } Matrix operator +(const Matrix &a,const Matrix &b) { Matrix c(a.n); for(int i=0;i<c.n;++i) for(int j=0;j<c.n;++j) c.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%mod; return c; } Matrix p(const Matrix& a,ll n) { Matrix x(a.n),y;x.Init(); y=a; while(n) { if(n&1) x=x*y; y=y*y; n>>=1; } return x; } Matrix f(const Matrix& a,ll n) { Matrix c(a.n); if(n==1) return c=a; if(n&1) return f(a,n-1)+p(a,n); c.Init(); return f(a,n/2)*(p(a,n/2)+c); } ll solve(ll n,int k) { if(n==1) return k; Matrix x(k),y(k); y.clear(); for(int i=0;i<k;++i) { y.mat[i][i]=k-i; if(i!=k-1) y.mat[i+1][i]=i+1; } x=f(y,n-1); return ((x.mat[k-1][0]+(k==1))*k)%mod; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,k; ll n; scanf("%d",&t); while(t--) { scanf("%I64d%d",&n,&k); printf("%I64d\n",solve(n,k)); } return 0; }
相关文章推荐
- HDU 4565——So Easy!(矩阵快速幂乘法)
- HDU 2294 Pendant (DP+矩阵快速幂降维)
- HDU 1575 Tr A (矩阵乘法)
- hdu 3483 矩阵乘法
- Hdu 2157 How many ways??(DP||矩阵乘法)
- hdu 2294 pendant
- HDU 4920 Matrix multiplication(矩阵乘法,cin,cout超时呀)
- hdu_1588_矩阵_求和_乘法_快速幂_斐波那契数列求前n项和
- HDU 3497 Mistwald【矩阵乘法】
- HDU 2294 Pendant
- HDU 5318(The Goddess Of The Moon-矩阵乘法)[Template:矩阵]
- hdu 1575 Tr A(矩阵乘法)
- PKU 2778 HDU 2243 AC自动机 + 矩阵乘法
- HDU 1575 Tr A (矩阵乘法)
- HDU 2294 Pendant
- 【矩阵乘法实践】HDU 1575——Tr A
- hdu 1757 A Simple Math Problem(矩阵乘法)
- HDU 4920 Matrix multiplication(矩阵乘法小技巧)——2014 Multi-University Training Contest 5
- 矩阵乘法模板之hdu——1751
- HDU - 2294 Pendant (DP滚动数组降维+矩阵高速功率)