2 条题解

  • 0
    @ 2026-2-3 9:47:39

    错排,用滚动数组省空间(虽然数据太小,省不了多少)

    公式推导:

    原本:

    D[i]=(i1)(D[i1]+D[i2])D[i]=(i-1)*(D[i-1]+D[i-2])

    推导:

    括号打开:D[i]=(i1)D[i1]+(i1)D[i2]D[i]=(i-1)*D[i-1]+(i-1)*D[i-2]

    D[i]=iD[i1]D[i1]+(i1)D[i2]D[i]=i*D[i-1]-D[i-1]+(i-1)*D[i-2]

    若按照我的代码的公式可知

    原式=D[i]=D[i]+1D[i1]+D[i1]1D[i]=D[i]+1-D[i-1]+D[i-1]-1 (i&1) D[i]=D[i]1D[i1]+D[i1]+1D[i]=D[i]-1-D[i-1]+D[i-1]+1 !(i&1)

    D[i]=D[i]D[i]=D[i]

    十分之不严谨,求巨巨改正^v^

    代码:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int dp[3];//用滚动数组省空间 
    signed main()
    {
        int n;cin>>n;
        dp[1]=1;
        for(int i=3;i<=n;i++)
        {
            dp[(i&1)^1]=dp[(i&1)]*i;//用滚动数组 
            if(i%2)dp[(i&1)^1]=dp[(i&1)^1]-1;
            else dp[(i&1)^1]=dp[(i&1)^1]+1;
        }
        printf("%lld\n",dp[(n&1)^1]);
        return 0;
    }
    
    • 0
      @ 2025-10-8 16:48:45

      G44 圆排列 错位排列

      #include<bits/stdc++.h>
      using namespace std;
      const int N = 21;
      long long D[N];
      int main()
      {
          D[1]=0,D[2]=1;
          for(int i=3; i<N; i++)D[i]=(i-1)*(D[i-1]+D[i-2]);
          int n;
          while(scanf("%d", &n)!=EOF) printf("%lld\n",D[n]);
          return 0;
      }
      
      • 1

      G44*【组合数:错排】错位排列

      信息

      ID
      241
      时间
      1000ms
      内存
      128MiB
      难度
      7
      标签
      递交数
      295
      已通过
      76
      上传者