逆序对数列(BZOJ 2431)
2024-10-21 13:26:57
题目描述
对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数。若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数。那么逆序对数为k的这样自然数数列到底有多少个?
输入
第一行为两个整数n,k。
输出
写入一个整数,表示符合条件的数列个数,由于这个数可能很大,你只需输出该数对10000求余数后的结果。
样例输入
4 1
样例输出
3
样例说明:
下列3个数列逆序对数都为1;分别是1 2 4 3 ;1 3 2 4 ;2 1 3 4;
测试数据范围
30%的数据 n<=12
100%的数据 n<=1000,k<=1000
/*
设f[i][j]为前i个数,逆序对数为j的方案数
在i-1个数中加入一个数,新增逆序对数为0~i-1,所以f[i][j]=Σf[i-1][k] (j-i+1<=k<=j)
时间复杂度为O(n^3),采用前缀和优化:f[i][j]=g[i-1][j]-g[i-1][j-i]
*/
#include<cstdio>
#include<iostream>
#define M 1010
#define Mod 10000
using namespace std;
int f[M][M],g[M][M];
int read()
{
char c=getchar();int flag=,num=;
while(c<''||c>''){if(c=='-')flag=-;c=getchar();}
while(c>=''&&c<=''){num=num*+c-'';c=getchar();}
return num*flag;
}
int main()
{
int n=read(),k=read();
f[][]=;
for(int i=;i<=k;i++)g[][i]=;
for(int i=;i<=n;i++)
for(int j=;j<=k;j++)
{
f[i][j]=g[i-][j];
if(j-i>=)f[i][j]=(f[i][j]+Mod-g[i-][j-i])%Mod;
if(j)g[i][j]=g[i][j-];
g[i][j]+=f[i][j];
g[i][j]%=Mod;
}
printf("%d",f[n][k]);
return ;
}
最新文章
- Java开发的几个注意点
- EasyTouch绑定事件在电脑上点击有效Android上无效的解决方法
- asp.net 对数据库表增加,删除,编辑更新修改
- 推荐几款制作网页滚动动画的 JavaScript 库
- thinkphp5命名规范
- Volley用法
- 除非 Windows Activation Service (WAS)和万维网发布服务(W3SVC)均处于运行状态,否则无法启动网站。目前,这两项服务均处于停止状态。
- Photoshop操作指南
- HDU 5029 Relief grain --树链剖分第一题
- org.springframework.web.context.ContextLoaderListen 报错解决办法
- 用xshell操作linux系统的常用命令
- (转载)顺序栈c++实现
- 正则表达式start(),end(),group()方法
- hdu 2032
- CaseFile
- Linux 环境下 fork 函数和 exec 函数族的使用
- Python中随机森林的实现与解释
- 百度编辑器ueditor 光标位置的坐标
- MySQL的sql_mode模式说明及设置
- android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]