zoukankan      html  css  js  c++  java
  • 51Nod 1250 排列与交换 —— DP

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250

    看了半天...

    把第一问想成逆序对的话似乎很容易想了,新加入一个数,可以往前挪动,增加的逆序对数就是它后面那些数的个数;

    所以 f[i][j] = ∑(k = max( 0 , j - i + 1)) f[i-1][k],用前缀和即可;

    第二问正好用第一类斯特林数;

    第一类斯特林数 str[i][j] 表示把 i 个数分成 j 个环,环有顺序的方案数,str[i][j] = str[i-1][j-1] (自成一环) + ( i - 1 ) * str[i-1][j] (跟到某个后面)

    对应到这道题,原来每个数自己是一个环,表示它就在自己的位置上;

    一个有顺序的环,按一个顺序往过数,一个数到下一个数相互交换,就对应了一种交换;

    str[i][j] 中,i - j 个数与别的环合并,也就是发生了一次交换,所以答案就是 ∑(n - k <= i <= n ) str[n][i]

    注意不要 MLE ...

    用滚动数组求斯特林数得注意一点,初值 str[0][0] 不要赋成1,然后后面 i == j 时也求出来即可,感性理解一下的话~

    这题...好像也不难啊。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const maxn=3005,mod=1000000007;
    int n,m;
    ll f[5][maxn],s[5][maxn],str[5][maxn],ans1,ans2;
    void init()
    {
    //    for(int i=0;i<=1;i++)str[i][i]=1;
        str[1][1]=1;//滚动数组!让初始化符合意义 
        for(int i=2;i<=n;i++)
            for(int j=1;j<=i;j++)//因为滚动所以 str[i][i]也在这里求 
            {
                int p=(i&1),q=!p;
                str[p][j]=(str[q][j-1]+(i-1)*str[q][j]%mod)%mod;
            }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        init();
        for(int i=0;i<=1;i++)
        {
            f[i][0]=1,s[i][0]=1;
            for(int j=1;j<=m;j++)s[i][j]+=s[i][j-1];
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                int p=(i&1),q=!p;
                if(j-i+1<=0)f[p][j]=s[q][j];
                else f[p][j]=(s[q][j]-s[q][j-i]+mod)%mod;
                if(j)s[p][j]=(s[p][j-1]+f[p][j])%mod;
                else s[p][j]=f[p][j];
            }
        int tmp=m;
        while(tmp>=0)ans1=(ans1+f[n&1][tmp])%mod,tmp-=2;
        for(int i=n-m;i<=n;i++)ans2=(ans2+str[n&1][i])%mod;
        printf("%lld %lld
    ",ans1,ans2);
        return 0;
    }
  • 相关阅读:
    HDU2027 统计元音 一点点哈希思想
    湖南工业大学第一届ACM竞赛 数字游戏 字符串处理
    湖南工业大学第一届ACM竞赛 我素故我在 DFS
    HDU3293sort
    HDU2082 找单词 母函数
    HDU1018 Big Number 斯特林公式
    湖南工业大学第一届ACM竞赛 分糖果 位操作
    UVA 357 Let Me Count The Ways
    UVA 147 Dollars
    UVA 348 Optimal Array Multiplication Sequence
  • 原文地址:https://www.cnblogs.com/Zinn/p/9606551.html
Copyright © 2011-2022 走看看