题意:给定一组数,q次查询(每次区间l~r),输出从a[l] 到a[r] 存在多少对逆序数。
分析:dp[l][r]表示从l~r的逆序数对数。首先算好dp[1][1..N]。
然后2~N枚举,每次计算从i开始的逆序对。dp[i][j]比dp[i-1][j]少了a[i-1]这个数的贡献。设一个累加器cnt。枚举i~N,若a[i-1]和a[j]构成逆序数,则cnt++;
最后dp[i][j]=dp[i-1][j]-cnt。
这题也可用树状数组,但感觉麻烦。
#include<iostream> using namespace std; #define N 1005 int dp[N][N]; int a[N]; int main() { int n,q,i,j,ans,l,r; while(scanf("%d%d",&n,&q)==2) { for(i=1;i<=n;i++) scanf("%d",&a[i]); memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { for(j=1;j<i;j++) if(a[i]<a[j]) dp[1][i]++; dp[1][i]+=dp[1][i-1]; } for(i=2;i<=n;i++) { ans=0; for(j=i;j<=n;j++) { if(a[i-1]>a[j]) ans++; dp[i][j]=dp[i-1][j]-ans; } } for(i=0;i<q;i++) { scanf("%d%d",&l,&r); printf("%d\n",dp[l][r]); } } return 0; }
HDU ACM 5273 Dylans loves sequence->DP
原文地址:http://blog.csdn.net/a809146548/article/details/46664115