CF1677A

div1
这是一场VP
过了两题,阻力很大,都调了很久,结果一看一道1600,一道1700

还是得画草稿,要写清楚每个数组的含义

[[DP]]

link: A - Tokitsukaze and Strange Inequality

一眼就能看出是DP,然后 根据这个数据范围,这就是n方DP

那么就是三次转移的计数

第一次,对位置i记它前面的数的出现次数前缀和
第二次,用上之前记的前缀和,把上次转移到的位置的\(a_i\)放在第二维
第三次,统计这个位置之前的,第二维比当前\(a_i\)大的方案和

每次都是 \(O(n^2)\)

#include<bits/stdc++.h>
using namespace std;
const int N=5005;
int f1[N][N],f2[N][N],f[N],T,n,a[N];
long long ans,sum[N];
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);ans=0;
		for(int i=1;i<=n;i++)scanf("%d",a+i);
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++)f1[i][j]=f[j];
			for(int j=1;j<=n;j++)f1[i][j]+=f1[i][j-1];
			f[a[i]]=1;
		}
		for(int i=1;i<=n;i++)for(int j=1;j<i;j++)f2[i][a[j]]=f1[j][a[i]-1];
		for(int i=1;i<=n;i++){
			for(int j=a[i]+1;j<=n;j++)ans+=sum[j];
			for(int j=1;j<=n;j++)sum[j]+=f2[i][j];
		}
		for(int i=1;i<=n;i++)f[i]=sum[i]=0;
		for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f1[i][j]=f2[i][j]=0;
		printf("%lld\n",ans);
	}
}

做得慢是因为开始的时候没有想清每个状态的意义就开始写了
以后绝对不能这样

posted @ 2022-12-11 11:49  -WD-  阅读(71)  评论(0)    收藏  举报