zoukankan      html  css  js  c++  java
  • dp

    Dexter considers a permutation of first N natural numbers good if it doesn’t have x and x+1 appearing
    consecutively, where (1 ≤ x < N). For example, for N = 3, all good permutations are:
    1. {1, 3, 2}
    2. {2, 1, 3}
    3. {3, 2, 1}
    Input
    Input starts with an integer T (≤ 10000), denoting the number of test cases.
    Each case starts with a line containing an integer N (1 ≤ N ≤ 106
    ).
    Output
    For each case, print the case number and the number of good permutations modulo 1000 000 007.
    Sample Input
    3
    2
    3
    5
    Sample Output
    Case 1: 1
    Case 2: 3
    Case 3: 53

    题目大意:

    对于整数 1 到 n 进行排列, 如果最终的排列结果没有出现 i + 1 正好在 i 的后一位的情况,就成这个排列是 good 的, 问对于整数 1 到 n 有多少种不同的排列方式是 good 的排列

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <algorithm>
    using namespace std;
    #define MM(a,b) memset(a,b,sizeof(a));
    #define inf 0x7f7f7f7f
    typedef long long ll;
    const ll mod=1e9+7;
    
    ll dp[1000000+10];
    int main()
    {
        int x,cas,kk=0;
        dp[1]=1;dp[2]=1;dp[3]=3;
        for(int i=4;i<=1e6;i++) dp[i]=(dp[i-1]*(i-1)%mod+(i-2)*dp[i-2]%mod)%mod;
        scanf("%d",&cas);
        while(cas--)
        {
            scanf("%d",&x);
            printf("Case %d: %lld
    ",++kk,dp[x]);
        }
        return 0;
    }
    

      

    这道题是一道推公式的数学题 f[i]表示n=i的good permutations

    f[i]=f[i-1]*(i-1)+f[i-2]*(i-2)

    其中f[i-1]*(i-1)很容易想到对于i-1合法排列插入i(只要i不插在i-1后就可以)这样的空位总共有i-1个

    例如对于n=4

    _1_3 2_

    _2_1_3

    _3 2_1_

    后面的f[i-2]*(i-2)稍稍难一点,我们可以考虑有一组x x+1相连的情况,只要把 i 插在x x+1之间就合法了。比如考虑n=5 对于2 3 1 4这样一组非法的序列在2 3间插入4就合法了。这时候计算总共有多少个仅有2 3相连的非法序列:

    因为仅有2 3相连所以把2 3看做一个整体(我们姑且把这个整体看做2)且要保证这个整体前面不是1后面不是4然后再变换一下:2 3整体看做2    比3大的数减1(这样4就变成了3 就不能排在2后面了 换句话说2 3 4肯定不会连在一起)问题就转化成了求i-2的合法序列数。

    2 3 1 4
      2   1 3

    像x x+1这样的在i-1中能组成i-2对,所以f[i-2]*(i-2)

    这样就推出f[i]=f[i-1]*(i-1)+f[i-2]*(i-2)

  • 相关阅读:
    IOS中多版本,多设备类型支持注意事项
    runtime
    网络搜集各种iOS开源类库
    Foudation框架常用结构体和常用类
    iOS开发-正则表达式的使用方法
    Github上的iOS资料-个人记录
    iOS应用程序多语言本地化
    星期判断
    【设定本地通知为周一到周五提醒, 周末不提醒解决办法】
    iOS9 HTTPS解决办法
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5696840.html
Copyright © 2011-2022 走看看