HDU 5273 Dylans loves sequence 区间DP

来源:互联网 发布:社交软件全球排名 编辑:程序博客网 时间:2024/05/13 04:42

题意:给你一个a[i]数组,i<N,每个询问给出leftright,求数组a[left]a[right]之间的逆序对数。

思路:区间DP,DP方程 : dp[i][j]=dp[i][j1]+dp[i+1][j]dp[i+1][j1]+(a[i]>a[j]);

(dp[i+1][j]dp[i+1][j1]) 表示从 i+1j1 有多少个比a[j]大的数,所有要计算a[i]是否比a[j]

QAQ:我dp数组没清空竟然也A了,后来想想,并不需要清空dp数组,因为dp[i][i]始终是0,其他的值每次都会根据dp[i][i]来重新计算。

http://acm.hdu.edu.cn/showproblem.php?pid=5273

/*********************************************    Problem : HDU 5273    Author  : NMfloat    InkTime (c) NM . All Rights Reserved .********************************************/#include <map>#include <set>#include <queue>#include <cmath>#include <ctime>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#define rep(i,a,b)  for(int i = a ; i <= b ; i ++)#define rrep(i,a,b) for(int i = b ; i >= a ; i --)#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next)#define cls(a,x)   memset(a,x,sizeof(a))#define eps 1e-8using namespace std;const int MOD = 1e9+7;const int INF = 0x3f3f3f3f;const int MAXN = 1e5;const int MAXE = 2e5;typedef long long LL;int T,n,m,k;int a[1005];int dp[1005][1005];void input() {    rep(i,1,n) scanf("%d",a+i);}void solve() {    cls(dp,0);    rep(k,1,n) { //k是区间长度,dp方程较长的区间由较短的区间得到,所以k放在前面。        rep(i,1,n) {            if(i+k>n) break;            int j = i + k;            dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1] + (a[i] > a[j]);            //dp[i+1][j] - dp[i+1][j-1] 表示从 i+1 到 j-1 有多少个比a[j]大的数,所有要计算a[i]>a[j]        }    }    int left,right;    rep(i,1,m) {        scanf("%d %d",&left,&right);        printf("%d\n",dp[left][right]);    }}int main(void) {    //freopen("a.in","r",stdin);    // scanf("%d",&T);    // while(T--) {    while(~scanf("%d %d",&n,&m)) {        input();        solve();    }    return 0;}
0 0
原创粉丝点击