• Luogu P5999 [CEOI2016]kangaroo


    Link
    转化为排列计数,要求满足下列限制的排列({a_n})的数量:
    (1.a_1=s,a_n=t)
    (2.forall iin(1,n),(a_i-a_{i-1})(a_{i+1}-a_i)<0)
    因为出现了大小关系限制,所以考虑从小到大放数字。
    (f_{i,j})表示现在放到第(i)个数,形成了(j)个连续段的方案数,同时记录(c)表示(s,t)这两个放了几个即边界放了几个。
    转移的话可以把(i)独自放一段,也可以用(i)连接两个连续段,(s,t)特殊处理。
    即:
    (i e swedge i e t:(j-c)f_{i-1,j-1}+jf_{i-1,j+1} ightarrow f_{i,j})
    (i=svee i=t:f_{i-1,j}+f_{i-1,j-1} ightarrow f_{i,j})
    答案就是(f_{n,1})

    #include<cstdio>
    #include<iostream>
    const int P=1000000007;
    int n,s,t,c,f[2007][2007];
    void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
    int mul(int a,int b){return 1ll*a*b%P;}
    int main()
    {
        scanf("%d%d%d",&n,&s,&t),f[1][1]=1,c=s==1;
        if(s>t) std::swap(s,t); else if(s==t) return !printf("0");
        for(int i=2;i<=n;++i)
        {
    	if(i==s||i==t) ++c;
    	for(int j=1;j<i;++j) i==s||i==t? (inc(f[i][j+1],f[i-1][j]),inc(f[i][j],f[i-1][j])):(inc(f[i][j+1],mul(f[i-1][j],j+1-c)),inc(f[i][j-1],mul(f[i-1][j],j-1)));
        }
        printf("%d",f[n][1]);
    }
    
  • 相关阅读:
    Docker学习总结(四)--应用部署
    strcat的由来
    ubuntu man不到pthread_mutex_XX
    string::front
    string::find_last_of
    string::find_last_not_of
    string::find_first_of
    string::find_first_not_of
    string::erase
    string::empty
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12253232.html
Copyright © 2020-2023  润新知