bzoj2431逆序对数列
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2431
很容易想到n^3的做法。就是前 i 个数用第 i 个数最多能 i - 1 个逆序对,所以 i - 1 个数中属于 j ~ j - i + 1 的值都能加到前 i 个数的状态上。
#include<iostream> #include<cstdio> #include<cstring> const int N=1005,mod=10000; int n,k,dp[N][N],sm[N]; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)sm[i]=sm[i-1]+i-1; dp[0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=k&&j<=sm[i];j++) for(int l=j;l>=0&&l>=j-i+1;l--) (dp[i][j]+=dp[i-1][l])%=mod; printf("%d",dp[n][k]); return 0; }
对于 i - 1 用了一个前缀和一样的部分。可以优化掉这个循环。只需要在过程中维护一下sum。很像之前做过的某道题。
不过sum还能变成负数?这样也能算出正确答案?感觉有些奇怪。
#include<iostream> #include<cstdio> #include<cstring> const int N=1005,mod=10000; int n,k,dp[N][N],sm[N],s[N]; int main() { scanf("%d%d",&n,&k); dp[0][0]=1; for(int i=1;i<=n;i++) { int sum=0; for(int j=0;j<=k;j++) { (sum+=dp[i-1][j])%=mod; if(j>=i)sum=((sum-dp[i-1][j-i])%mod+mod)%mod; dp[i][j]=sum; } } printf("%d",dp[n][k]); return 0; }