• Tetrahedron(Codeforces Round #113 (Div. 2) + 打表找规律 + dp计数)


    题目链接:

      https://codeforces.com/contest/166/problem/E

    题目:

    题意:

      给你一个三菱锥,初始时你在D点,然后你每次可以往相邻的顶点移动,问你第n步回到D点的方案数。

    思路:

      打表找规律得到的序列是0,3,6,21,60,183,546,1641,4920,14763,通过肉眼看或者oeis可以得到规律为

      dp计数:dp[i][j]表示在第i步时站在位置j的方案数,j的取值为[0,3],分别表示D,A,B,C点,转移方程肯定是从其他三个点转移。

    代码实现如下:

     非dp计数:

     1 #include <set>
     2 #include <map>
     3 #include <deque>
     4 #include <queue>
     5 #include <stack>
     6 #include <cmath>
     7 #include <ctime>
     8 #include <bitset>
     9 #include <cstdio>
    10 #include <string>
    11 #include <vector>
    12 #include <cstdlib>
    13 #include <cstring>
    14 #include <iostream>
    15 #include <algorithm>
    16 using namespace std;
    17 
    18 typedef long long LL;
    19 typedef pair<LL, LL> pLL;
    20 typedef pair<LL, int> pLi;
    21 typedef pair<int, LL> pil;;
    22 typedef pair<int, int> pii;
    23 typedef unsigned long long uLL;
    24 
    25 #define lson rt<<1
    26 #define rson rt<<1|1
    27 #define lowbit(x) x&(-x)
    28 #define name2str(name) (#name)
    29 #define bug printf("*********
    ")
    30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    31 #define FIN freopen("D://code//in.txt","r",stdin)
    32 #define IO ios::sync_with_stdio(false),cin.tie(0)
    33 
    34 const double eps = 1e-8;
    35 const int mod = 1000000007;
    36 const int maxn = 1e7 + 7;
    37 const double pi = acos(-1);
    38 const int inf = 0x3f3f3f3f;
    39 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    40 
    41 int n;
    42 LL dp[maxn];
    43 
    44 int qpow(int x, int n) {
    45     int res = 1;
    46     while(n) {
    47         if(n & 1) res = 1LL * res * x % mod;
    48         x = 1LL * x * x % mod;
    49         n >>= 1;
    50     }
    51     return res;
    52 }
    53 
    54 int main(){
    55     int inv = qpow(4, mod - 2);
    56     LL cnt = 1;
    57     scanf("%d", &n);
    58     for(int i = 1; i <= n; i++) {
    59         cnt = cnt * 3 % mod;
    60         if(i & 1) dp[i] = (cnt - 3 + mod) % mod * inv % mod;
    61         else dp[i] = (cnt + 3) % mod * inv % mod;
    62     }
    63     printf("%lld
    ", dp[n]);
    64     return 0;
    65 }

    dp计数代码:

     1 #include <set>
     2 #include <map>
     3 #include <deque>
     4 #include <queue>
     5 #include <stack>
     6 #include <cmath>
     7 #include <ctime>
     8 #include <bitset>
     9 #include <cstdio>
    10 #include <string>
    11 #include <vector>
    12 #include <cstdlib>
    13 #include <cstring>
    14 #include <iostream>
    15 #include <algorithm>
    16 using namespace std;
    17 
    18 typedef long long LL;
    19 typedef pair<LL, LL> pLL;
    20 typedef pair<LL, int> pLi;
    21 typedef pair<int, LL> pil;;
    22 typedef pair<int, int> pii;
    23 typedef unsigned long long uLL;
    24 
    25 #define lson rt<<1
    26 #define rson rt<<1|1
    27 #define lowbit(x) x&(-x)
    28 #define name2str(name) (#name)
    29 #define bug printf("*********
    ")
    30 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    31 #define FIN freopen("D://code//in.txt","r",stdin)
    32 #define IO ios::sync_with_stdio(false),cin.tie(0)
    33 
    34 const double eps = 1e-8;
    35 const int mod = 1000000007;
    36 const int maxn = 1e7 + 7;
    37 const double pi = acos(-1);
    38 const int inf = 0x3f3f3f3f;
    39 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    40 
    41 int n;
    42 int dp[maxn][4];
    43 
    44 int main(){
    45     scanf("%d", &n);
    46     dp[0][0] = 1;
    47     for(int i = 1; i <= n; i++) {
    48         for(int j = 0; j < 4; j++) {
    49             for(int k = 0; k < 4; k++) {
    50                 if(j == k) continue;
    51                 dp[i][j] = (1LL * dp[i][j] + dp[i-1][k]) % mod;
    52             }
    53         }
    54     }
    55     printf("%d
    ", dp[n][0]);
    56     return 0;
    57 }

    BM代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <string>
      7 #include <map>   
      8 #include <set>
      9 #include <cassert>
     10 using namespace std;
     11 #define rep(i,a,n) for (int i=a;i<n;i++)
     12 #define per(i,a,n) for (int i=n-1;i>=a;i--)
     13 #define pb push_back
     14 #define mp make_pair
     15 #define all(x) (x).begin(),(x).end()
     16 #define fi first
     17 #define se second
     18 #define SZ(x) ((int)(x).size())
     19 typedef vector<int> VI;
     20 typedef long long ll;
     21 typedef pair<int,int> PII;
     22 const ll mod=1000000007;
     23 ll powmod(ll a,ll b) {
     24     ll res=1;
     25     a%=mod;
     26     assert(b>=0);
     27     for(; b; b>>=1) {
     28         if(b&1)res=res*a%mod;
     29         a=a*a%mod;
     30     }
     31     return res;
     32 }
     33 // head
     34 int _,n;
     35 namespace linear_seq {
     36 const int N=100100;
     37 ll res[N],base[N],_c[N],_md[N];
     38 vector<int> Md;
     39 void mul(ll *a,ll *b,int k) {
     40     rep(i,0,k+k) _c[i]=0;
     41     rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
     42     for (int i=k+k-1; i>=k; i--) if (_c[i])
     43             rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
     44     rep(i,0,k) a[i]=_c[i];
     45 }
     46 int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
     47 //        printf("%d
    ",SZ(b));
     48     ll ans=0,pnt=0;
     49     int k=SZ(a);
     50     assert(SZ(a)==SZ(b));
     51     rep(i,0,k) _md[k-1-i]=-a[i];
     52     _md[k]=1;
     53     Md.clear();
     54     rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
     55     rep(i,0,k) res[i]=base[i]=0;
     56     res[0]=1;
     57     while ((1ll<<pnt)<=n) pnt++;
     58     for (int p=pnt; p>=0; p--) {
     59         mul(res,res,k);
     60         if ((n>>p)&1) {
     61             for (int i=k-1; i>=0; i--) res[i+1]=res[i];
     62             res[0]=0;
     63             rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
     64         }
     65     }
     66     rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
     67     if (ans<0) ans+=mod;
     68     return ans;
     69 }
     70 VI BM(VI s) {
     71     VI C(1,1),B(1,1);
     72     int L=0,m=1,b=1;
     73     rep(n,0,SZ(s)) {
     74         ll d=0;
     75         rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
     76         if (d==0) ++m;
     77         else if (2*L<=n) {
     78             VI T=C;
     79             ll c=mod-d*powmod(b,mod-2)%mod;
     80             while (SZ(C)<SZ(B)+m) C.pb(0);
     81             rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
     82             L=n+1-L,B=T,b=d,m=1;
     83         } else {
     84             ll c=mod-d*powmod(b,mod-2)%mod;
     85             while (SZ(C)<SZ(B)+m) C.pb(0);
     86             rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
     87             ++m;
     88         }
     89     }
     90     return C;
     91 }
     92 int gao(VI a,ll n) {
     93     VI c=BM(a);
     94     c.erase(c.begin());
     95     rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
     96     return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
     97 }
     98 };
     99 int main() {
    100     scanf("%d",&n);
    101     printf("%d
    ",linear_seq::gao(VI{0,3,6,21,60,183,546,1641,4920,14763},n-1));
    102 }

    三份代码跑的时间如下(忽略MLE那发,从上到下分别为BM,DP,公式):

  • 相关阅读:
    SQL_server 将表中的记录 转换成 Insert(插入) SQL 语句
    Delphi DBGridEh导出Excel
    hdu 2018 母牛的故事
    hdu 2084 数塔
    hdu 2190 重建希望小学
    hdu 2501 Tiling_easy version
    hdu 2046 骨牌铺方格
    hdu 2045 不容易系列之(3)—— LELE的RPG难题
    高精度模板
    各种平面分割问题总结(转)
  • 原文地址:https://www.cnblogs.com/Dillonh/p/10447282.html
Copyright © 2020-2023  润新知