[AHOI2009] BZOJ2431 逆序对数列-动态规划-前缀和优化

来源:互联网 发布:ftp同步数据库备份 编辑:程序博客网 时间:2024/05/17 04:48

传送门

题目大意:求逆序对数为k的长为n的排列有多少?n,k<=1000

题解:这显然是个DP(废话)

而且dp[n][k]表示长为n逆序对数为k的方案数。

而且状态转移显然要从dp[n-1][...]推过来。

考虑如果把n插入到1~(n-1)的某个逆序对数为x的排列的第p个数的后面,

那么会新产生(n-1)-(p+1)+1=n-p-1对新的逆序对,其中0<=p<=n-1是显然的。

因此如果当前状态dp[n][k],那么上一个状态就是dp[n-1][x=k-(n-p-1)=p+k+1-n]。

那么显然要求p+k+1-n>=0,因此p>=n-k-1,因此max(0,n-k-1)<=p<=n-1。

状态转移方程为:dp[n][k]=sum{dp[n-1][p+k+1-n]},max(0,n-k-1)<=p<=n-1。

状态是O(n^2)的,转移是O(n)的,O(n^3)肯定要T。

优化其实是显然的,因为要求和,没有限制条件,还是连续区间,显然用前缀和优化。

具体来说,将max(0,n-k-1)<=p<=n-1代入到状态转移方程中“来源状态”的第二维,

可以得到dp[n][k]对于dp[n-1][..]的求和区间是[max(0,n-k-1)+k+1-n,k]。

所以再用sumn[n][k]表示sum{dp[n][x]},0<=x<=k。

那么dp[n][k]=sumn[n-1][k]-sumn[n-1][max(0,n-k-1)+k-n]。

这里实现有一个细节,就是第二个sumn的第二维有可能是-1,这个时候sumn=0,要特判一下。

另外一个细节是,对于每一个sumn[n][比较大的...],后面比较大的...也要算全了,即使后面的dp[n][比较大的...]=0(不存在),因为状态转移需要。

这样转移的时间复杂度降到O(1),总复杂度O(N^2)。

我的代码就写到这里了,又去看了看别人的做法,其实可以优化空间复杂度和编码复杂度(一会看看我的代码就知道我的代码有多乱和容易写错了)

空间复杂度O(N^2)看起来很不清真啊,首先由于dp[n]和sumn[n]都是由n-1转移来的,所以可以滚动数组优化到O(N)。

(注意并不是dp[N][2],而是dp[N],可以滚动到真的只需要一维,具体实现留给大家思考)。

但编程还是要考虑上文提到的两个细节。注意到求和区间是非减的,所以可以用一个变量代替sumn数组,实现方式类似于可行性完全背包分组+单调队列的做法,编程复杂度特别低。而且不需要考虑上述两个细节。

代码:

//BZOJ 2431//AHOI 2009#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define MAXN 1010#define mod 10000using namespace std;int dp[MAXN][MAXN],sumn[MAXN][MAXN];int main(){int n,k;scanf("%d%d",&n,&k);dp[1][0]=sumn[1][0]=sumn[1][1]=1;for(int i=2;i<=n;i++){dp[i][0]=sumn[i][0]=1;for(int j=1;j<=min(k,i*(i-1)/2);j++){int a=max(i-j-1,0),b;if(j-i+a<0) b=0;else b=sumn[i-1][j-i+a];dp[i][j]=(sumn[i-1][j]-b)%mod;sumn[i][j]=(sumn[i][j-1]+dp[i][j])%mod;}for(int j=min(k,i*(i-1)/2)+1;j<=min(k,i*(i+1)/2);j++)sumn[i][j]=sumn[i][j-1];}dp[n][k]=(dp[n][k]+mod)%mod;printf("%d\n",dp[n][k]);return 0;}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝打喷嚏流清鼻涕怎么办 宝宝感冒流清鼻涕怎么办 2岁感冒流清鼻涕怎么办 小孩感冒流清鼻涕怎么办 4岁宝宝半夜发烧怎么办 四岁宝宝免疫力低下怎么办 两岁宝宝咳嗽流鼻涕怎么办 小婴儿流清鼻涕怎么办 14个月宝宝流鼻涕怎么办 小孩一直流黄鼻涕怎么办 咳嗽有痰 浓鼻涕怎么办 儿童鼻窦炎总反复流脓鼻涕怎么办? 宝宝感冒咳嗽流黄鼻涕怎么办 哺乳期感冒流清鼻涕怎么办 哺乳期打喷嚏流清鼻涕怎么办 哺乳期妈妈感冒流清鼻涕怎么办 哺乳期严重流清鼻涕怎么办 小孩每天都是脓鼻涕怎么办 夏天小孩咳嗽流黄脓鼻涕怎么办? 受凉了流清鼻涕怎么办 宝宝50多天鼻塞怎么办 50多天孩子咳嗽怎么办 2岁宝宝伤风鼻塞怎么办 2个月伤风鼻塞怎么办 3个月宝宝鼻塞怎么办 感冒治好后咳嗽一直不好怎么办 天气太热感冒了怎么办 3个月的婴儿鼻塞怎么办 四个月宝宝感冒鼻塞严重怎么办 4个月小孩鼻塞怎么办 4个多月的宝宝流鼻涕怎么办 4个月大的宝宝流鼻涕怎么办 两岁宝宝着凉了怎么办 7岁儿童晚上鼻塞怎么办 儿童感冒鼻塞怎么办速效办法 7岁儿童感冒鼻塞怎么办 七个月婴儿感冒流鼻涕怎么办 婴儿感冒流鼻涕怎么办速效办法 三个月婴儿感冒咳嗽流鼻涕怎么办 五个月婴儿感冒咳嗽流鼻涕怎么办 两个多月的宝宝鼻塞怎么办