P1433 吃奶酪 题解

msjing写的比较明白的一道状压

solve

  • 求最小,考虑dp|二分,思考dp
  • \(n<=15\),可以状压
  • 设计状态,f[i]为第i个情况下最小距离,其中i是2进制压缩数
  • 发现还需要上一次最后的位置,再开一维,f[i][j]表示从j转移来的第i个情况的最小距离
  • 如何转移?枚举i的位置,如果这一位为0,表示可以转移,就可以转,然后枚举所有能转移来的位置
  • 搞完了喵
  • 只用注意坐标也是实数就行

code

  • 给出19行不压行清新代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
constexpr int maxn=17;
int n;
long double f[1<<maxn][maxn];
pair<long double,long double> p[maxn];
long double dou(long double x) {return x*x;}
long double get(long double x1,long double y1,long double x2,long double y2) {return sqrt(dou(x1-x2)+dou(y1-y2));}
int main()
{
	cin >> n;for (int i=1;i<=n;i++) cin >> p[i].first >> p[i].second;
	for (int i=0;i<(1<<n);i++) for (int j=0;j<=n;j++) f[i][j]=1e6;f[0][0]=0.00;
	for (int i=0;i<(1<<n);i++) for (int j=0;j<n;j++) if (!((i>>j)&1)) for (int k=0;k<=n;k++) f[i+(1<<j)][j+1]=min(f[i+(1<<j)][j+1],f[i][k]+get(p[k].first,p[k].second,p[j+1].first,p[j+1].second));
	long double ans=DBL_MAX;
	for (int i=0;i<=n;i++) ans=min(ans,f[(1<<n)-1][i]);
	printf("%.2Lf\n",ans);
	return 0;
}

压行的

posted @ 2026-06-26 10:44  msjing  阅读(8)  评论(0)    收藏  举报