照着标答写90
查看原帖
照着标答写90
1037870
jianxing04楼主2024/1/13 18:29

照着第一篇题解的思路为何只有90,我的代码如下

#include<bits/stdc++.h>
using namespace std;
int n;
double x[20],y[20];
double Dis(int i,int j)
{
    return sqrt(pow(x[i]-x[j],2)+pow(y[i]-y[j],2));
}
double Len[20][20];
double ans[20][35000];
int main()
{
    memset(ans,127,sizeof(ans));
    cin>>n;
    x[0]=0;
    y[0]=0;
    int T=(1<<n)-1;
    for (int i=1;i<=n;i++)
    {
        cin>>x[i]>>y[i];
    }
    for (int i=0;i<n;i++)
    {
        for (int j=i+1;j<=n;j++)
        {
            Len[i][j]=Dis(i,j);
            Len[j][i]=Len[i][j];
        }
    }
    for (int i=1;i<=n;i++)
    {
        ans[i][1<<i-1]=Len[0][i];
    }
    for (int i=1;i<(1<<n);i++)
    {
        for (int j=1;j<=n;j++)
        {
            if (i&(1<<(j-1))==0)
            {
                continue;
            }
            for (int k=1;k<=n;k++)
            {
                if (k==j||i&(1<<(k-1))==0)
                {
                    continue;
                }
                ans[j][i]=min(ans[j][i],ans[k][i-(1<<(j-1))]+Len[k][j]);
            }
        }
    }
    double Min=ans[1][T];
    for (int i=2;i<=n;i++)
    {
        Min=min(Min,ans[i][T]);
    }
    printf("%.2lf",Min);
    system("pause");
	return 0;
}

第一篇题解如下

#include <cstdio>
#include <cstring> 
#include <cmath> 
#define min(a,b) (((a)<(b))?(a):(b)) 
//洛谷 P1433 吃奶酪 状压DP
double a[20][20];//预处理,从第i块到第j块的距离,使用两点之间距离公式 
double x[20],y[20];//每块奶酪的横、纵坐标
double F[18][34000];//状压DP数组 在第i个点上,走过的二进制状态的十进制表达为j时,最短的距离 
int N; 
double distance(int v,int w)//计算第v个和第w个奶酪之间的距离 
{
	return sqrt((x[v]-x[w])*(x[v]-x[w])+(y[v]-y[w])*(y[v]-y[w]));//两点间距离公式 
}
int main()
{
	int i,j,k;
	double ans;
	memset(F,127,sizeof(F));//这样可以给浮点数赋值无穷大 
	ans=F[0][0];
	scanf("%d",&N);
	for(i=1;i<=N;i++)
	{
		scanf("%lf%lf",&x[i],&y[i]);//数据读入 
	}
	x[0]=0;y[0]=0;
	for(i=0;i<=N;i++)
	{
		for(j=i+1;j<=N;j++)
		{
			a[i][j]=distance(i,j);//初始化距离数组 
			a[j][i]=a[i][j];
		}
	} 
	for(i=1;i<=N;i++)//初始化 
	{
		F[i][(1<<(i-1))]=a[0][i];//在i点上且只有经过i点时距离是原点到i点的距离 
	}
	for(k=1;k<(1<<N);k++)//枚举所有二进制的状态 
	{
		for(i=1;i<=N;i++)
		{
			if((k&(1<<(i-1)))==0)
				continue;//i的位置没被走过,所以不需要再继续计算了 
			for(j=1;j<=N;j++)
			{
				if(i==j)
					continue;//同一个点不需要再计算 
				if((k&(1<<(j-1)))==0)
					continue;//j的位置没走过  
				F[i][k]=min(F[i][k],F[j][k-(1<<(i-1))]+a[i][j]);
			} 
		} 
	} 
	for(i=1;i<=N;i++)
	{
		ans=min(ans,F[i][(1<<N)-1]);
	}
	printf("%.2f\n",ans);
}
2024/1/13 18:29
加载中...