【五校联考3day2】C

这题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;
}
转载需注明出处。
原文地址:https://www.cnblogs.com/jz929/p/11817614.html