换个方向转移就过了是咋回事?
查看原帖
换个方向转移就过了是咋回事?
6322
woshiren楼主2020/10/27 17:18

思路来自于题解 甚至可以说代码很像…… AC:(题解中的转移方式)

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const double eps=1e-8;
int n,m,dp[1<<20],T,state[20][20];
double x[20],y[20],a,b;
void calc(int i,int j,double &a,double &b)
{
	a=(y[i]*x[j]-y[j]*x[i])/(x[i]*x[j]*(x[i]-x[j]));
	b=(y[j]*x[i]*x[i]-y[i]*x[j]*x[j])/(x[i]*x[j]*(x[i]-x[j]));
}
int main()
{
	//freopen("P2831_1.in","r",stdin);
	scanf("%d",&T);
	for (int F=1;F<=T;F++)
	{
		scanf("%d%d",&n,&m);
		for (int i=0;i<n;i++)
			scanf("%lf%lf",&x[i],&y[i]);
		memset(state,0,sizeof(state));
		for (int i=0;i<n;i++)
		{
			for (int j=0;j<n;j++)
			{
				if (i==j) continue;
				if (abs(x[i]-x[j])<=eps) continue;
				calc(i,j,a,b);
				if(a>-eps) continue; 
				for (int k=0;k<n;k++)
				{
					if (abs(a*x[k]*x[k]+b*x[k]-y[k])<=eps)
						state[i][j]|=(1<<k);
				}
			}
		}
		memset(dp,0x3f,sizeof(dp));
		dp[0]=0;
		for (int i=0;i<(1<<n);i++)
		{
			for (int j=0;j<n;j++)
			{
				if (i&(1<<j)) continue;
				dp[i|(1<<j)]=min(dp[i|(1<<j)],dp[i]+1);
				for (int k=0;k<n;k++)
				{
					dp[i|state[j][k]]=min(dp[i|state[j][k]],dp[i]+1);
				}
			}
		}
		printf("%d\n",dp[(1<<n)-1]);
	}
	return 0;
} 

WA ON #8:个人认为这种转移想起来更加自然,当然实质上是一样的

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const double eps=1e-9;
int n,m,dp[1<<20],T,state[20][20];
double x[20],y[20],a,b;
void calc(int i,int j,double &a,double &b)
{
	a=(y[i]*x[j]-y[j]*x[i])/(x[i]*x[j]*(x[i]-x[j]));
	b=(y[j]*x[i]*x[i]-y[i]*x[j]*x[j])/(x[i]*x[j]*(x[i]-x[j]));
}
int main()
{
	//freopen("P2831_1.in","r",stdin);
	scanf("%d",&T);
	for (int F=1;F<=T;F++)
	{
		scanf("%d%d",&n,&m);
		for (int i=0;i<n;i++)
			scanf("%lf%lf",&x[i],&y[i]);
		memset(state,0,sizeof(state));
		for (int i=0;i<n;i++)
		{
			for (int j=0;j<n;j++)
			{
				if (i==j) continue;
				if (abs(x[i]-x[j])<=eps) continue;
				calc(i,j,a,b);
				if(a>-eps) continue; 
				for (int k=0;k<n;k++)
				{
					if (abs(a*x[k]*x[k]+b*x[k]-y[k])<=eps)
						state[i][j]|=(1<<k);
				}
			}
		}
		memset(dp,0x3f,sizeof(dp));
		dp[0]=0;
		for (int i=1;i<(1<<n);i++)
		{
			for (int j=0;j<n;j++)
			{
				if (i&(1<<j))
				{
					dp[i]=min(dp[i^(1<<j)]+1,dp[i]);
					for (int k=0;k<n;k++)
					{
						if ((i|state[j][k])==i) dp[i]=min(dp[i^state[j][k]]+1,dp[i]);
					}
				}
			}
		}
		printf("%d\n",dp[(1<<n)-1]);
	}
	return 0;
} 
2020/10/27 17:18
加载中...