zoukankan      html  css  js  c++  java
  • [矩阵加速]土豪送项链

    题目描述

    土豪给心上人做珍珠项链,他有K种珍珠,每种N颗,为了炫富,他每种珍珠都要用上。问他能做几种长度[1,N]的首饰。答案要模1234567891。

    输入

    第一行输入一个T(代表T组数据)

    接下来T行,每行一个N,一个K,用空格隔开

    1 ≤ T ≤ 10 

    1 ≤ N ≤ 1,000,000,000 

    1 ≤ K ≤ 30

    输出

    共T行

    每行一个对应N,K的结果

    样例输入

    2
    2 1
    3 2

    样例输出

    2
    8

    温馨提醒您:

    数据千万条,清零第一条,多测不清零,爆零两行泪

    样例解释:

    第一组数据:N=1,K=1时只有1种;N=2,K=1时只有1种,所以一共是2种

    第二组数据:N=1,K=2时0种;N=2,K=2时有2种;N=3,K=2时有6种,所以一共是8种

    are you 明白?

    解题思路

    首先我们这道题很明显是一个dp,可以说是双重DP。

    我们先设一个ans[i]表示当[1,i]的方案总数。

    那么很显然。ans[i] = dp[1][k] + dp[2][k].... + dp[i][k]。

    我们就需要求出dp[i][j].

    dp[i][j]表示长度为i,j个珍珠。

    经过推算dp[i][j] = (k - (j - 1)) * dp[i - 1][j - 1] + j * dp[i - 1][j]

    如何理解呢,我们想一下,如果需要长度为i,并且用到j个珍珠,那么它可以是两种状态转移过来

    1.长度为i - 1的用了j - 1种珍珠,那么只能在(k - (j - 1))中选一种珍珠,于是乘dp[i - 1][j - 1]。

    2.长度为i - 1的用了j种珍珠,那么只能再在这j种珍珠中再选一种来用,于是就是dp[i - 1][j] * j。

    那么

    就很好构造了。

    我们的初始矩阵egin{bmatrix} ans[i] & f[i][1] & f[i][2] & ... & f[i][k] end{bmatrix}

    我们需要转移成这样egin{bmatrix} ans[i + 1] & f[i + 1][1] & f[i + 1][2] & ... & f[i + 1][k] end{bmatrix}

    那么加速矩阵其实就很好推出来了。

    egin{bmatrix} 1 & 0 & 0 & 0 & . & . & . & & & \ 0& 1 & (k-1) & 0 & . & . & . & & & \ 0& 0 & 2 & (k - 2) & . & . & . & & & \ 0& 0 & 0& 3& . & . & .& & & \ .& .& .& .& .& .& . & & & \ .& .& .& .& . & . & . & & & \ .& .& .& .& .& .& . & & & \ 0& 0& 0 &0 . & . &. &. & & & \ 0 & 0& 0& 0&. & . & . & & & \ 1 & 0& 0& 0& . & . & . & & & end{bmatrix}

    相信你也发现了规律....

    int main(){
        scanf ("%d",&t);
        while (t -- ){
            memset(A.c,0,sizeof(A.c));
            memset(B.c,0,sizeof(B.c));
            memset(C.c,0,sizeof(C.c));
            scanf ("%d%d",&n,&k);
            A.n = 1;
            A.m = k + 1;
            A.c[1][1] = 0;
            A.c[1][2] = k;
            B.n = B.m = k + 1;
            B.c[1][1] = B.c[k + 1][1] = 1;
            for (int i = 2;i <= k + 1;i ++){
                B.c[i][i] = i - 1;
                B.c[i][i + 1] = k - (i - 1);
            }
            C = A * qkpow(B,n);
            printf("%lld
    ",C.c[1][1]);
        }
    }
  • 相关阅读:
    一段滚动文字的js (jQuery)
    VB ASP 使用 now() 时默认格式调整方法
    解决标题过长的CSS
    javascript Spline代码
    统计学中的几个重要的分布
    网页游戏开发秘笈 PDF扫描版
    网页设计与开发——HTML、CSS、JavaScript (王津涛) pdf扫描版
    网页设计与开发:HTML、CSS、JavaScript实例教程 (郑娅峰) pdf扫描版
    网页DIV+CSS布局和动画美化全程实例 (陈益材) 随书光盘
    实用掌中宝--HTML&CSS常用标签速查手册 PDF扫描版
  • 原文地址:https://www.cnblogs.com/lover-fucker/p/13566682.html
Copyright © 2011-2022 走看看