bzoj2431[HAOI2009]逆序对数列

天哪天哪天哪

我们用f[i][j]来表示前i个数,有j对逆序对的方案数,so考虑插入,因为i比1到i-1里面的任何一个数都要大,所以插入的时候后面有多少个数,就会多出多少逆序对,所以前面的符合条件的都可以转移,f[i][j]=sigma(f[i-1][j-k]),k属于0到i-1,然而前缀和神烦.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
#define N 1005
#define inf 10000
int f[N][N],s[N][N];
int n,m;

int main()
{
	scanf("%d%d",&n,&m);
	memset(f,0,sizeof(f));
	memset(s,0,sizeof(s));
	f[1][0]=1;
	fo(i,0,m)s[1][i]=1;
	fo(i,2,n)
	{
		fo(j,0,m)
		{
			f[i][j]=s[i-1][j];
			f[i][j]%=inf;
			if(j-i>=0)
			{
				f[i][j]-=s[i-1][j-i];
				f[i][j]+=inf;
				f[i][j]%=inf;
			}
			if(j)s[i][j]=s[i][j-1];
			s[i][j]+=f[i][j];
			s[i][j]%=inf;
//			s[i][j]=f[i][j];else s[i][j]=s[i][j-1]+f[i][j];
		}
	}
	cout<<f[n][m]<<endl;
	return 0;
}


你可能感兴趣的:(dp)