[关闭]
@lychee123 2017-09-11T14:31:07.000000Z 字数 1091 阅读 907

矩阵优化

数论


题面链接:HDU 6185:Covering


题意

求用 的格子去填满 的矩阵一共有多少种方法

分析

通过模板找出他们之间的关系式,然后对于该模板进行小细节的改动就OK(我这写的啥阿)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int mod = 1000000007;
  4. typedef long long LL;
  5. const int M = 4;
  6. const int base[M][M] =
  7. {
  8. { 1, 5, 1, -1 },
  9. { 1, 0, 0, 0 },
  10. { 0, 1, 0, 0 },
  11. { 0, 0, 1, 0 },
  12. }; //需要进行k次方的矩阵,通过关系式推出的矩阵方程
  13. const int source[M][M] =
  14. {
  15. { 36, 0, 0, 0 },
  16. { 11, 0, 0, 0 },
  17. { 5, 0, 0, 0 },
  18. { 1, 0, 0, 0 },
  19. }; //用于存答案的矩阵
  20. struct Mat //矩阵
  21. {
  22. int a[M][M]; //矩阵数据
  23. Mat() //矩阵默认构造函数,初始化数据全0
  24. {
  25. memset(a, 0, sizeof(a));
  26. }
  27. Mat(const int g[M][M]) //有参构造函数,拷贝给定数组的元素作为矩阵数据
  28. {
  29. memcpy(a, g, sizeof(a));
  30. }
  31. void E() //构造单位矩阵,这个如果要用,应该位于默认构造之后
  32. {
  33. for (int i = 0; i < M; i++)
  34. a[i][i] = 1;
  35. }
  36. Mat operator * (const Mat &b) const //重载矩阵乘法
  37. {
  38. Mat ret;
  39. for (int i = 0; i < M; i++)//此处要改M代表与M项相关
  40. for (int k = 0; k < M; k++)
  41. {
  42. if (a[i][k] == 0)
  43. continue;
  44. for (int j = 0; j < M; j++)
  45. {
  46. ret.a[i][j] += (LL)a[i][k] * b.a[k][j] % mod;
  47. if (ret.a[i][j] >= mod)
  48. ret.a[i][j] -= mod;
  49. if (ret.a[i][j] < 0)
  50. ret.a[i][j] += mod; //矩阵中用负数,取模要注意
  51. }
  52. }
  53. return ret;
  54. }
  55. };
  56. Mat bin(const Mat &a, LL k)
  57. {
  58. Mat ret;
  59. ret.E();
  60. Mat res;
  61. res = a;
  62. while (k)
  63. {
  64. if (k & 1)
  65. ret = ret * res;
  66. res = res * res;
  67. k >>= 1;
  68. }
  69. return ret;
  70. }
  71. int main()
  72. {
  73. LL n;
  74. while (~scanf("%lld", &n))
  75. {
  76. Mat ret = bin(Mat(base), n - 1);
  77. ret = ret * Mat(source);
  78. printf("%d\n", ret.a[3][0]);
  79. }
  80. return 0;
  81. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注