传送门
目前只会
n2
n
2
的
dp
d
p
做法。
设
dp[i][j]
d
p
[
i
]
[
j
]
表示
1
1
~的排列逆序对为
j
j
的方案数。显然这个东西是可以递推的。相当于将插入到
1
1
~的排列中,然后就可以从
dp[i−1][k]
d
p
[
i
−
1
]
[
k
]
转移过来。
然后我们就惊奇的发现这个方法是
O(n3)
O
(
n
3
)
的,显然会
T
T
掉。
如何优化?
仔细观察会发现,是由
dp[i−1]
d
p
[
i
−
1
]
的前缀和转移过来的,因此每次枚举
i
i
之后,我们维护一个叫做的东西来表示
dp[i−1]
d
p
[
i
−
1
]
的前缀和然后就能
O(n2)
O
(
n
2
)
转移了。
代码如下:
#include<bits/stdc++.h>
#define N 1005
#define mod 10000
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
return ans;
}
int dp[N][N],ans=0,n,k;
int main(){
n=read(),k=read();
memset(dp,0,sizeof(dp));
dp[1][0]=1;
for(int i=2;i<=n;++i){
ans=0;
for(int j=0;j<=k;++j){
ans=(ans+dp[i-1][j])%mod;
dp[i][j]=ans%mod;
if(j+1-i>=0)ans=(ans-dp[i-1][j-i+1]+mod)%mod;
}
}
printf("%d",dp[n][k]);
return 0;
}