SP64 PERMUT1 - Permutations 题解

题目传送门

前置知识

动态规划基础

解法

\(f_{i,j}\) 表示 \(1 \sim i\) 的全排列中存在 \(j\) 个逆序对的方案数,状态转移方程为 \(f_{i,j}=\sum\limits_{k=j-\min(i-1,j)}^{j}f_{i-1,k}=\sum\limits_{k=0}^{j}f_{i-1,k}-\sum\limits_{k=0}^{j-\min(i-1,j)-1}f_{i-1,k}\)

需要前缀和和滚动数组优化。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
ll f[10010],g[2][10010];
int main()
{
    ll n,m,t,i,j,k;
    cin>>t;
    for(k=1;k<=t;k++)
    {
        cin>>n>>m;
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        f[0]=1;
        for(i=0;i<=m;i++)
        {
            g[1][i]=((i==0)?0:g[1][i-1])+f[i];
        }
        for(i=2;i<=n;i++)
        {
            for(j=0;j<=m;j++)
            {
                f[j]=g[(i-1)&1][j]-((j-min(i-1,j)-1<0)?0ll:g[(i-1)&1][j-min(i-1,j)-1]);
                g[i&1][j]=((j==0)?0:g[i&1][j-1])+f[j];
            }
        }
        cout<<f[m]<<endl;
    }
    return 0;
}

后记

多倍经验:luogu P6323 [COCI2006-2007#4] ZBRKA | luogu P2513 [HAOI2009] 逆序对数列 | luogu P2513 [HAOI2009] 逆序对数列

posted @ 2024-04-07 09:02  hzoi_Shadow  阅读(2)  评论(0编辑  收藏  举报
扩大
缩小