Permutation Descent Counts(UVALive 7787)

本文深入探讨了Permutation Descent Count (PDC)问题的动态规划解法,详细解释了如何通过考虑逆序数来计算特定顺序下具有指定数量下降的排列数。文章提供了完整的代码实现,并说明了在计算过程中如何避免大数溢出,采用模运算确保数值在合理范围内。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Given a positive integer, N, a permutation of order N is a one-to-one (and thus onto) function from
the set of integers from 1 to N to itself. If p is such a function, we represent the function by a list of
its values:
[p(1)p(2). . . p(N)]
For example,
[5 6 2 4 7 1 3] represents the function from {1 . . . 7} to itself which takes 1 to 5, 2 to 6, . . ., 7 to 3.
For any permutation p, a descent of p is an integer k for which p(k) > p(k + 1). For example, the
permutation [5 6 2 4 7 1 3] has a descent at 2(6 > 2) and 5(7 > 1).
For permutation p, des§ is the number of descents in p. For example, des([5624713]) = 2. The
identity permutation is the only permutation with des§ = 0. The reversing permutation with p(k) =
N + 1 − k is the only permutation with des§ = N − 1.
The permutation descent count (PDC) for given order N and value v is the number of permutations
p of order N with des§ = v. For example:
P DC(3, 0) = 1{[123]}
P DC(3, 1) = 4{[132], [213], [231], 312]}
P DC(3, 2) = 1{[321]}
Write a program to compute the PDC for inputs N and v. To avoid having to deal with very large
numbers, your answer (and your intermediate calculations) will be computed modulo 1001113.

Input

The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets
that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input. It contains the data set number, K, followed by the
integer order, N (2 ≤ N ≤ 100), followed by an integer value, v (0 ≤ v ≤ N − 1).

Output

For each data set there is a single line of output. The single output line consists of the data set number,
K, followed by a single space followed by the PDC of N and v modulo 1001113 as a decimal integer.

Sample Input

4
1 3 1
2 5 2
3 8 3
4 99 50

Sample Output

1 4
2 66
3 15619
4 325091

题解:

第一次做时想到了是dp,但没有去深究,后来发现就是dp,之前做过类似的,每回插入时考虑一下插入的位置就好(补充一下吧,dp[i][j]的i代表串的长度,j代表逆序数,查找dp[i][j]的个数时考虑长度为i-1,逆序数为j或者j-1的情况即可,如果为j,只需保持逆序数在最后或者j个逆序之间插入,如果为j-1,只需增加1逆序数,有i-j个方法数

代码如下:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define maxn 27
#define N 100000000
#define INF 0x3f3f3f3f
#define mod 1001113
#define e  2.718281828459045
#define eps 1.0e18
#define PI acos(-1)
#define lowbit(x) (x&(-x))
#define read(x) scanf("%d",&x)
#define put(x) prllf("%d\n",x)
#define memset(x,y) memset(x,y,sizeof(x))
#define Debug(x) cout<<x<<" "<<endl
#define lson i << 1,l,m
#define rson i << 1 | 1,m + 1,r
#define ll long long
//std::ios::sync_with_stdio(false);
//cin.tie(NULL);
//const int maxn=;
using namespace std;

int a[111][111];
void init()
{
    for(int i=0; i<=100; i++)
        a[i][0]=1;
    for(int i=1; i<=100; i++)
        for(int j=1; j<i; j++)
            a[i][j]=(a[i-1][j]*(j+1)%mod+a[i-1][j-1]*(i-j)%mod)%mod;
}
int main()
{
    init();
    int t;
    cin>>t;
    while(t--)
    {
        int p,n,m;
        cin>>p>>n>>m;
        cout<<p<<" "<<a[n][m]<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值