这个题。。我们可以想到用递推写!!qwq(好吧,其实我的DP水平不高啊qwq)

就是我们以两个为单位(一共九种组合情况),然后往后面推下一位的情况。

通过手动模拟,我们可以找到它们之间的递推关系(详见代码)

先放上我的暴力代码。。。。(60分)

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #define mod 1000000007
  6. using namespace std;
  7. long long f[2][10];
  8. int t,cnt=1;
  9. struct Node{int id,que;long long ans=0;}node[1010];
  10. bool cmp1(struct Node x,struct Node y)
  11. {
  12. if(x.que<y.que) return 1;
  13. else return 0;
  14. }
  15. bool cmp2(struct Node x,struct Node y)
  16. {
  17. if(x.id<y.id) return 1;
  18. else return 0;
  19. }
  20. inline int read()
  21. {
  22. int f=1,x=0; char ch=getchar();
  23. while(ch<'0'||ch>'9')
  24. {
  25. if(ch=='-') f=-1;
  26. ch=getchar();
  27. }
  28. while(ch<='9'&&ch>='0')
  29. {
  30. x=x*10+ch-'0';
  31. ch=getchar();
  32. }
  33. return x*f;
  34. }
  35. int main()
  36. {
  37. freopen("food.in","r",stdin);
  38. freopen("food.out","w",stdout);
  39. t=read();
  40. //scanf("%d",&t);
  41. for(int i=1;i<=t;i++) node[i].que=read(),node[i].id=i;
  42. //scanf("%d",&node[i].que),node[i].id=i;
  43. sort(node+1,node+1+t,cmp1);
  44. //cout<<endl;
  45. //for(int i=1;i<=t;i++)
  46. // printf("%d ",node[i].que);
  47. f[0][1]=2;
  48. f[0][2]=3;
  49. f[0][3]=2;
  50. f[0][4]=3;
  51. f[0][5]=2;
  52. f[0][6]=2;
  53. f[0][7]=2;
  54. f[0][8]=2;
  55. f[0][9]=2;
  56. while(node[cnt].que==1) node[cnt].ans=3,cnt++;
  57. while(node[cnt].que==2) node[cnt].ans=9,cnt++;
  58. while(node[cnt].que==3) node[cnt].ans=20,cnt++;
  59. for(int i=1;i<=node[t].que-3;i++)
  60. {
  61. f[1][1]=(f[0][4]+f[0][8])%mod;
  62. f[1][2]=(f[0][1]+f[0][4]+f[0][8])%mod;
  63. f[1][3]=(f[0][1]+f[0][4])%mod;
  64. f[1][4]=(f[0][2]+f[0][5]+f[0][7])%mod;
  65. f[1][5]=(f[0][2]+f[0][7])%mod;
  66. f[1][6]=(f[0][2]+f[0][5])%mod;
  67. f[1][7]=(f[0][6]+f[0][9])%mod;
  68. f[1][8]=(f[0][3]+f[0][9])%mod;
  69. f[1][9]=(f[0][3]+f[0][6])%mod;
  70. //for(int j=1;j<10;j++)
  71. // printf("f[1][%d]=%lld\n",j,f[1][j]);
  72. for(int j=1;j<10;j++)
  73. swap(f[0][j],f[1][j]);
  74. while(i==node[cnt].que-3)
  75. {
  76. long long ans=0;
  77. for(int j=1;j<10;j++)
  78. ans=(ans+f[0][j])%mod;
  79. node[cnt].ans=ans;
  80. // cout<<"ans="<<ans<<endl;
  81. cnt++;
  82. }
  83. }
  84. sort(node+1,node+1+t,cmp2);
  85. for(int i=1;i<=t;i++)
  86. printf("%lld\n",node[i].ans%mod);
  87. return 0;
  88. }

然后我们看到数据范围。。。好大呀qwq线性算法肯定会T啊qwq,那。。。。写矩阵加速吧!qwq

其实有了暴力程序之后矩阵很好写(就是把对应的行和列上面的数设成1,然后做一次矩阵乘法就相当于一次转移。

详见代码:

  1. #include<iostream>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<cstdio>
  5. #define mod 1000000007
  6. using namespace std;
  7. int t;
  8. int f[10];
  9. struct Node{long long m[10][10];}node;
  10. inline Node mul(Node x,Node y)
  11. {
  12. Node cur;
  13. for(int i=1;i<=9;i++)
  14. for(int j=1;j<=9;j++)
  15. cur.m[i][j]=0;
  16. for(int i=1;i<=9;i++)
  17. for(int j=1;j<=9;j++)
  18. for(int k=1;k<=9;k++)
  19. cur.m[i][j]=(cur.m[i][j]+x.m[i][k]*y.m[k][j])%mod;
  20. return cur;
  21. }
  22. inline void solve(Node x)
  23. {
  24. int cur[10];
  25. memset(cur,0,sizeof(cur));
  26. for(int j=1;j<=9;j++)
  27. for(int k=1;k<=9;k++)
  28. cur[j]=(cur[j]+f[k]*x.m[k][j])%mod;
  29. for(int i=1;i<=9;i++)
  30. f[i]=cur[i];
  31. }
  32. int main()
  33. {
  34. scanf("%d",&t);
  35. while(t--)
  36. {
  37. for(int i=1;i<=9;i++)
  38. for(int j=1;j<=9;j++)
  39. node.m[i][j]=0;
  40. node.m[1][4]=1,node.m[1][8]=1;
  41. node.m[2][1]=1,node.m[2][4]=1,node.m[2][8]=1;
  42. node.m[3][1]=1,node.m[3][4]=1;
  43. node.m[4][2]=1,node.m[4][5]=1,node.m[4][7]=1;
  44. node.m[5][2]=1,node.m[5][7]=1;
  45. node.m[6][2]=1,node.m[6][5]=1;
  46. node.m[7][6]=1,node.m[7][9]=1;
  47. node.m[8][3]=1,node.m[8][9]=1;
  48. node.m[9][3]=1,node.m[9][6]=1;
  49. memset(f,0,sizeof(f));
  50. int n;
  51. for(int i=1;i<=9;i++) f[i]=1;
  52. scanf("%d",&n);
  53. n-=2;
  54. while(n)
  55. {
  56. if(n&1) solve(node);
  57. node=mul(node,node);
  58. n>>=1;
  59. }
  60. long long ans=0;
  61. for(int i=1;i<=9;i++)
  62. ans=(ans+f[i])%mod;
  63. printf("%lld\n",ans%mod);
  64. }
  65. return 0;
  66. }

食物(矩阵快速幂)(DP)的更多相关文章

  1. codeforces 691E 矩阵快速幂+dp

    传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...

  2. P1357 花园 (矩阵快速幂+ DP)

    题意:一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 m <= 5  n <= 1e15 题解:用一个m位二进制表示状态 转移很好想 但是这个题是用矩阵快速 ...

  3. BZOJ1009 矩阵快速幂+DP+KMP

    Problem 1009. -- [HNOI2008]GT考试 1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: ...

  4. Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP

    题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...

  5. COJ 1208 矩阵快速幂DP

    题目大意: f(i) 是一个斐波那契数列 , 求sum(f(i)^k)的总和 由于n极大,所以考虑矩阵快速幂加速 我们要求解最后的sum[n] 首先我们需要思考 sum[n] = sum[n-1] + ...

  6. Codeforces 954 dijsktra 离散化矩阵快速幂DP 前缀和二分check

    A B C D 给你一个联通图 给定S,T 要求你加一条边使得ST的最短距离不会减少 问你有多少种方法 因为N<=1000 所以N^2枚举边数 迪杰斯特拉两次 求出Sdis 和 Tdis 如果d ...

  7. Codeforces 989E A Trance of Nightfall 矩阵快速幂+DP

    题意:二维平面上右一点集$S$,共$n$个元素,开始位于平面上任意点$P$,$P$不一定属于$S$,每次操作为选一条至少包含$S$中两个元素和当前位置$P$的直线,每条直线选取概率相同,同一直线上每个 ...

  8. BZOJ1009: [HNOI2008]GT考试 (矩阵快速幂 + DP)

    题意:求一个长度为n的数字字符串 (n <= 1e9) 不出现子串s的方案数 题解:用f i,j表示长度为i匹配到在子串j的答案 用kmp的失配函数预处理一下 然后这个转移每一个都是一样的 所以 ...

  9. bzoj2004 矩阵快速幂优化状压dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=2004 以前只会状压dp和矩阵快速幂dp,没想到一道题还能组合起来一起用,算法竞赛真是奥妙重重 小Z ...

  10. ZZNU 2182 矩阵dp (矩阵快速幂+递推式 || 杜教BM)

    题目链接:http://47.93.249.116/problem.php?id=2182 题目描述 河神喜欢吃零食,有三种最喜欢的零食,鱼干,猪肉脯,巧克力.他每小时会选择一种吃一包. 不幸的是,医 ...

随机推荐

  1. 认识单元测试(jar包资源网址:http://search.maven.org/)

    单元测试在3.8版本以前只需要导入一个jar包,3.8版本以后需要导入二个jar包.(网址:http://junit.org/junit4/) package com.huawei.junit; im ...

  2. input 隐藏边框

    style='border-left:0px;border-top:0px;border-right:0px;border-bottom:1px; border-bottom-color:Black'

  3. 使用opencv-python画OpenCV LOGO

    OpenCV2-Python 官方教程的练习 代码: #-*- coding:utf-8 -*- import numpy as np import cv2 img = np.zeros((512, ...

  4. Kubuntu上连接PPTP

    生活在天朝,如果没备几招FQ的本领,都不敢说自己还活着... 前两天从朋友那抢了个VPN帐号,使用的是PPTP的,在google上找了一会,发现网上大都是讲VPN服务搭建的,就算是介绍客户端的,也大都 ...

  5. 每个内存大小:sudo dmidecode -t memory |grep -A16 "Memory Device$" |grep "Size:"

    CPU: 型号:grep "model name" /proc/cpuinfo |awk -F ':' '{print $NF}' 数量:lscpu |grep "CPU ...

  6. Luogu 4725 【模板】多项式对数函数

    继续补全模板. 要求 $$g(x) = ln f(x)$$ 两边求导, $$g'(x) = \frac{f'(x)}{f(x)}$$ 然后左转去把多项式求导和多项式求逆的模板复制过来,就可以计算出$g ...

  7. python中fork()函数生成子进程分析-乾颐堂

    python的os module中有fork()函数用于生成子进程,生成的子进程是父进程的镜像,但是它们有各自的地址空间,子进程复制一份父进程内存给自己,两个进程之 间的执行是相互独立的,其执行顺序可 ...

  8. [SoapUI] 通过SoapUI发送POST请求,请求的body是JSON格式的数据

    通过SoapUI发送POST请求,请求的body是JSON格式的数据: data={"currentDate":"2015-06-19","reset ...

  9. WindowServer2016无法安装.netframework3.5

    因为安装sql server的原因 需要安装.NET Framework3.5 报错内容如下: 原因分析 找不到安装源文件. 解决办法 可以通过如下 PowerShell 脚本进行安装: 从开始菜单中 ...

  10. osg反走样

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits-& ...