分析
计数题,一眼DP。
但是这个限制条件比较多,怎么样才能在犬牙交错的区间限制当中设计状态?我们先假设字符串全部都是0,怎么样添加1去让他符合条件。
假设我们从左到右构建字符串,当前我们放置第i个字符,并且确保所有以第 个字符结束的子串都是有
效的。为了计算以第i 个字符结尾的字符串中不同字符的数量,我们需要知道什么?
每次转移要检查以 i i i 结尾的是否满足所有的限制条件,但是如果不满足也没关系,在后面某个位置会检查的。
每次的check就根据最后一个0/1的位置就行。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=998244353;
int n,a[110][110];
ll f[110][110];
bool check(int x,int last)
{
for(int i=1;i<=x;i++)
{
if(a[i][x]==0) continue;
if(a[i][x]==1&&i<=last) return false;
if(a[i][x]==2&&i>last) return false;
}
return true;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
cin>>a[i][j];
}
}
if(a[1][1]!=2) f[1][0]=2;
else f[1][0]=0;
for(int i=1;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(check(i+1,j)) f[i+1][j]=(f[i+1][j]+f[i][j])%mod;
if(check(i+1,i)) f[i+1][i]=(f[i+1][i]+f[i][j])%mod;
}
}
ll ans=0;
for(int i=0;i<=n-1;i++)
{
ans=(ans+f[n][i])%mod;
}
cout<<ans%mod;
return 0;
}