题解:P12220 [蓝桥杯 2023 国 Java B] 星球
题解:P12220 [蓝桥杯 2023 国 Java B] 星球
思路简述
可以看到
所谓状压 DP,其精髓在于状态压缩,通过将状态转化为二进制的方式进行动态规划,利用二进制中只有
定义
dp[i][j]=min(dp[i][j],dp[i^(1<<j-1)][k]+dis(a[j].x,a[j].y,a[j].z,a[k].x,a[k].y,a[k].z)*a[j].w);。
其中
代码呈现
C++
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=20;
int n,m;
double dp[1<<N][N],mmin=DBL_MAX;
struct node{int x,y,z,w;}a[N];
double dis(int x,int y,int z,int xx,int yy,int zz){return sqrt((xx-x)*(xx-x)+(yy-y)*(yy-y)+(zz-z)*(zz-z));}//空间中两点计算公式
signed main(){
cin>>n;
memset(dp,127,sizeof(dp));
for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y>>a[i].z>>a[i].w,dp[1<<i-1][i]=0;
dp[0][0];
int num=1<<n;
for(int i=0;i<num;i++)
for(int j=1;j<=n;j++)
if((i>>j-1)&1)//确保j在状态i中
for(int k=1;k<=n;k++)
if((i>>k-1)&1)//确保k在状态i中
dp[i][j]=min(dp[i][j],dp[i^(1<<j-1)][k]+dis(a[j].x,a[j].y,a[j].z,a[k].x,a[k].y,a[k].z)*a[j].w);//利用题目中能量的计算公式进行转移
for(int i=1;i<=n;i++) mmin=min(mmin,dp[num-1][i]);//枚举不同的结束点取最小值
printf("%.2lf",mmin);
return 0;
}