CF1542D Priority Queue 题解
经过感性剖析,他显然是个 \(dp\)
假定我们找到了处于位置 \(t\) 的一个 \(+x\) 设 \(dp[i][j]\) 表示到第 \(i\) 位为止,集合中有 \(j\) 个数 \(<=x\) 的方案数。
操作序列是数组 \(a\) ,我们的目的是要让我们选定的这个到最后并对答案产生贡献,我们分成以下几种情况讨论
当 \(i<t\) 时
若这一位是 \(-\) ,那么 \(dp[i][j] = dp[i-1][j] + dp[i-1][j+1]\) 如果不选,他就是上一位直接继承下来
但如果选,他就相当于删去了一个数,也就是说原来是 \(j+1\)
并且特别的,若 $ j=0 $ ,需要在上式的基础上再加 $ dp[i-1][0] $
当 $ i=t $ 时
根据我们给的定义,这里是必选的 \(dp[i][j]=dp[i][j-1]\)
当 \(i>t\) 时
其实和 \(i<t\) 差不多
若是 \(-\) ,不存在特殊情况,因为此时我们找的那个 \(x\) 已经在序列中了
若是 \(+x\) 大于我们找的那个值
那么 \(dp[i][j]=dp[i-1][j]*2\)
如果小于把 \(j+1\) 就行了
最后统计答案
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
const int mod=998244353;
const int maxn=610;
struct node{
int x;
bool plus;//判断是哪种操作
}a[maxn];
int dp[maxn][maxn];
signed main()
{
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
{
char ch;
cin>>ch;
if(ch=='+')
{
a[i].plus=true;
cin>>a[i].x;
}
else a[i].plus=false;
}
for(int t=1;t<=n;t++)
{
if(a[t].plus)
{
memset(dp,0,sizeof(dp));//每一次dp都要清零
int at=a[t].x;
dp[0][0]=1;//初始状态
for(int i=1;i<t;i++)//i<t的情况
{
if(!a[i].plus)//如果第i位是-
{
for(int j=0;j<=n;j++)
{
dp[i][j]+=dp[i-1][j+1];//累加选的方案
dp[i][j]%=mod;
}
for(int j=0;j<=n;j++)
{
dp[i][j]+=dp[i-1][j];//累加不选的方案
dp[i][j]%=mod;
}
dp[i][0]=dp[i][0]+dp[i-1][0];//特殊情况
dp[i][0]%=mod;
/*
这是因为会有两种情况:
1. 根据题意,若没有 $+x$ ,就不管他
2. 若删去的数比 $x$ 大,也是 $dp[i-1][0]$
所以要多加一遍
*/
}
else//如果第i位是+x
{
if(a[i].x>at)
{
for(int j=0;j<=n;j++)
{
dp[i][j]+=(dp[i-1][j]*2)%mod;//选与不选均不会对j有影响
dp[i][j]%=mod;
}
}
else
{
for(int j=0;j<=n;j++)
{
dp[i][j]+=dp[i-1][j]%mod;//不选
dp[i][j]%=mod;
}
for(int j=1;j<=n;j++)
{
dp[i][j]+=dp[i-1][j-1]%mod;//选
dp[i][j]%=mod;
}
}
}
}
for(int i=0;i<=n;i++)//i=t的情况
{
dp[t][i]=dp[t-1][i];
}
for(int i=t+1;i<=n;i++)//i>t的情况
{
if(!a[i].plus)
{
for(int j=0;j<=n;j++)
{
dp[i][j]+=dp[i-1][j];//不选
dp[i][j]%=mod;
}
for(int j=0;j<=n;j++)
{
dp[i][j]+=dp[i-1][j+1];//选
dp[i][j]%=mod;
}
}
else
{
if(a[i].x>=at)
{
for(int j=0;j<=n;j++)
{
dp[i][j]+=dp[i-1][j]*2%mod;//同上一种情况
dp[i][j]%=mod;
}
}
else
{
for(int j=0;j<=n;j++)
{
dp[i][j]+=dp[i-1][j]%mod;//同上一种情况
dp[i][j]%=mod;
}
for(int j=1;j<=n;j++)
{
dp[i][j]+=dp[i-1][j-1]%mod;
dp[i][j]%=mod;
}
}
}
}
int tmp=0;
for(int i=0;i<=n;i++)//计算总的贡献
{
tmp+=(dp[n][i]*a[t].x)%mod;
tmp%=mod;
}
ans+=tmp;
ans%=mod;
}
}
cout<<ans;
}

浙公网安备 33010602011771号