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);
}
}
做得慢是因为开始的时候没有想清每个状态的意义就开始写了
以后绝对不能这样

浙公网安备 33010602011771号