这题DP,想明白了就可以了。
这就像个坐标系一样(好像本来就是。。。)
而在其上面,有很多个点。
咳咳,有点丑。
然后呢,我们就按照x坐标排个序,y也顺便排一下(第二关键字)
这样子,在我们DP的时候,
或者说对于i,我们可以满足a[i].x<=a[i+1…n].x
所以,我们就可以不记录对于i点射向左边的了。
而我们要记录的,是它射向右边的最上面的点(j),射向右边的最下面的点(k),射向上面的最下面的点(l),射向下面的最上面的点(o)。
也就是f[i][j][k][l][o]!!!
要转移的话,我们便枚举当前点所射的方向。
我这里设向上为0,向左为1,向下为2,向右为3。
然后判断一下它是否合法即可,记得更新一下j,k,l,o。(详细见标)
上标:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define mo 998244353
using namespace std;
struct node{int x,y;}a[55];
int n,b[55],f[2][55][55][55][55],x=1,las=0,t,tt;
bool bz[55][4];
ll ans=0;
inline int read()
{
int x=0,f=0; char c=getchar();
while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return f ? -x:x;
}
int cmp(node x,node y) {return x.x==y.x ? x.y<y.y:x.x<y.x;}
int main()
{
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
n=read();
for (int i=1;i<=n;i++)
a[i].x=read(),a[i].y=read();
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
if (a[i].x==a[j].x)
{
if (a[i].y<a[j].y) bz[i][0]=bz[j][2]=1;
else bz[i][2]=bz[j][0]=1;
}
else if (a[i].y==a[j].y)
{
if (a[i].x>a[j].x) bz[i][1]=bz[j][3]=1;
else bz[i][3]=bz[j][1]=1;
}
f[0][0][0][0][0]=1;
for (int i=1;i<=n;i++)
{
for (int j=0;j<i;j++)
for (int k=0;k<i;k++)
for (int l=0;l<i;l++)
for (int o=0;o<i;o++)
{
if (!f[las][j][k][l][o]) continue;
// j:最上面的3,k:最下面的3,l:最下面的0,o:最上面的2
// i->0
if (!bz[i][0] && (a[i].y>a[j].y || j==0))
{
t=(a[i].y<a[l].y || l==0) ? i:l;
(f[x][j][k][t][o]+=f[las][j][k][l][o])%=mo;
}
// i->1
if (!bz[i][1] && (a[i].y<a[l].y || l==0) && (a[i].y>a[o].y || o==0))
{
(f[x][j][k][l][o]+=f[las][j][k][l][o])%=mo;
}
// i->2
if (!bz[i][2] && (a[i].y<a[k].y || k==0))
{
t=(a[i].y>a[o].y || o==0) ? i:o;
(f[x][j][k][l][t]+=f[las][j][k][l][o])%=mo;
}
// i->3
if (!bz[i][3])
{
t=(a[i].y>a[j].y || j==0) ? i:j;
tt=(a[i].y<a[k].y || k==0) ? i:k;
(f[x][t][tt][l][o]+=f[las][j][k][l][o])%=mo;
}
}
las=x,x^=1;
for (int j=0;j<i;j++)
for (int k=0;k<i;k++)
for (int l=0;l<i;l++)
for (int o=0;o<i;o++)
f[x][j][k][l][o]=0;
}
for (int j=0;j<=n;j++)
for (int k=0;k<=n;k++)
for (int l=0;l<=n;l++)
for (int o=0;o<=n;o++)
ans+=f[las][j][k][l][o];
printf("%lld
",ans%mo);
return 0;
}