首页 > 其他分享 >洛谷 P1433 吃奶酪

洛谷 P1433 吃奶酪

时间:2024-08-09 21:53:55浏览次数:10  
标签:洛谷 16 int double 奶酪 P1433 20 include

原题icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1433

Description

房间里放着 n 块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在 (0,0)点处。

Input

第一行有一个整数,表示奶酪的数量 n。

第 2 到第(n+1) 行,每行两个实数,第(i+1) 行的实数分别表示第 i 块奶酪的横纵坐标xi​,yi​。

Output

输出一行一个实数,表示要跑的最少距离,保留 2 位小数。

Sample 1

InputOutput
4
1 1
1 -1
-1 1
-1 -1
7.41

Hint

数据规模与约定

对于全部的测试点,保证 1≤n≤15,∣xi​∣,∣yi​∣≤200,小数点后最多有 2 位数字。

提示

解题思路

状态dp:

状态压缩的思想是用二进制来表示状态。用一个整数的二进制形式的每一个二进制位 0 或 1 表示一个状态。

在这里表示n块奶酪,就代表有n位二进制,每一位2进制代表一块奶酪。

例:100110 代表第2、3、6块奶酪已经吃到。

        111111 代表所有奶酪吃到。

状态转移方程:Fi,k=min⁡(Fi,k,Fj,k−2i−1+Ai,j)Fi,k​=min(Fi,k​,Fj,k−2i−1​+Ai,j​)

Fj,k−2i−1​ 为在 j 点且没有走过 i 点的最短距离, Ai,j​ 是从 i 到 j 的距离。

AC代码

状态dp

#include <iostream>
using namespace std;
#include <cstring>
#include <cmath>
#include <algorithm>
int n;
double a[16][16],x[16],y[16],f[16][33000];
//计算距离
double distance(int v,int w){
	return sqrt((x[v]-x[w])*(x[v]-x[w])+(y[v]-y[w])*(y[v]-y[w]));
}
int main(){
	cin>>n;
	x[0]=y[0]=0;
	for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
	memset(f,127,sizeof(f));
    //计算每块奶酪直接的距离
	for(int i=0;i<=n;i++){
		for(int j=i+1;j<=n;j++) a[i][j]=a[j][i]=distance(i,j);
	}
    //初始化每块奶酪的距离
	for(int i=1;i<=n;i++) f[i][1<<(i-1)]=a[0][i];
	for(int k=1;k<(1<<n);k++){
		for(int i=1;i<=n;i++){
			if((k&(1<<(i-1)))==0) continue;    //没走过的路跳过
			for(int j=1;j<=n;j++){
				if(i==j) continue;            //相等直接跳过
				if((k&(1<<(j-1)))==0) continue; //没走过的路跳过
				f[i][k]=min(f[i][k],f[j][k-(1<<(i-1))]+a[i][j]); 
			}
		}
	}
	double ans=f[0][0];
	for(int i=1;i<=n;i++) ans=min(ans,f[i][(1<<n)-1]);
	printf("%.2lf",ans); 
}

dfs(超时)

#include<iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int n,flag[20];
double x[20],y[20],a[20][20];
bool vis[20];
double Min=0x3ffffffffffff;
void dfs(int k,double d){
	if(d>Min) return ;
	if(k>n){
		Min=d;
		return;
	}
	for(int i=1;i<=n;i++){
		if(vis[i]==0){
			vis[i]=1;
			flag[k]=i;
			dfs(k+1,d+a[flag[k-1]][flag[k]]);
			vis[i]=0;
		}
	}
} 
int main(){
	cin>>n;
	x[0]=y[0]=0;
	for(int i=1;i<=n;i++) {
		cin>>x[i]>>y[i];
	}
	for(int i=0;i<=n;i++){
		for(int j=0;j<=n;j++){
			a[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
		}
	} 
	dfs(1,0.0);

	printf("%.2lf\n",Min);
}

标签:洛谷,16,int,double,奶酪,P1433,20,include
From: https://blog.csdn.net/j2189259313/article/details/141066028

相关文章

  • 洛谷 P3870 开关之线段树板子
    洛谷P3870题解传送锚点摸鱼环节[TJOI2009]开关题目描述现有\(n\)盏灯排成一排,从左到右依次编号为:\(1\),\(2\),……,\(n\)。然后依次执行\(m\)项操作。操作分为两种:指定一个区间\([a,b]\),然后改变编号在这个区间内的灯的状态(把开着的灯关上,关着的灯打开);指定一个区间......
  • 题解 洛谷P1478 陶陶摘苹果(升级版)
    题目传送门https://www.luogu.com.cn/problem/P1478截图来自洛谷:这道题就是这道题的升级版而已,我们可以定义一个结构体分别存抓当前苹果的力气与高度。之后进行从第1个苹果到第n个苹果的循环,判断当前苹果高度是否够,力气是否够。最重要的是要排序,因为要摘得苹果最多,所以要先......
  • 洛谷P1194 买礼物之警钟敲爆
    洛谷P1194题解传送锚点摸鱼环节买礼物题目描述又到了一年一度的明明生日了,明明想要买\(B\)样东西,巧的是,这\(B\)样东西价格都是\(A\)元。但是,商店老板说最近有促销活动,也就是:如果你买了第\(I\)样东西,再买第\(J\)样,那么就可以只花\(K_{I,J}\)元,更巧的是,\(K_{I,......
  • 洛谷:P1308 [NOIP2011 普及组] 统计单词数
    题目描述一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要......
  • 洛谷 P1019 [NOIP2000 提高组] 单词接龙 题解
    暴搜!!暴搜!!暴搜!!重要的事情说三遍#include<bits/stdc++.h>usingnamespacestd;constintN=25;intn,ans,use[N];strings,word[N];voiddfs(strings){intls=s.size();//s的lengthans=max(ans,ls);//求出最长的单词接龙for(inti=0;i<n......
  • 洛谷P2404 自然数的拆分问题——题解
    洛谷P2404题解传送锚点摸鱼环节自然数的拆分问题题目描述任何一个大于\(1\)的自然数\(n\),总可以拆分成若干个小于\(n\)的自然数之和。现在给你一个自然数\(n\),要求你求出\(n\)的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列......
  • 洛谷 P1125 [NOIP2008 提高组] 笨小猴
    [NOIP2008提高组]笨小猴题目描述笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!这种方法的具体描述如下:假设maxn......
  • 洛谷P1064 金明的预算方案——题解
    洛谷P1064题解传送锚点摸鱼环节[NOIP2006提高组]金明的预算方案题目描述金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过\(n\)元钱就行”。今天......
  • 洛谷P8869 莲子的软件工程学之警钟长鸣
    洛谷P8869题解传送锚点摸鱼环节[传智杯#5初赛]A-莲子的软件工程学题目背景在宇宙射线的轰击下,莲子电脑里的一些她自己预定义的函数被损坏了。对于一名理科生来说,各种软件在学习和研究中是非常重要的。为了尽快恢复她电脑上的软件的正常使用,她需要尽快地重新编写这么一......
  • 洛谷P3842 线段——题解
    洛谷P3842题解传送锚点摸鱼环节[TJOI2007]线段题目描述在一个\(n\timesn\)的平面上,在每一行中有一条线段,第\(i\)行的线段的左端点是\((i,L_{i})\),右端点是\((i,R_{i})\)。你从\((1,1)\)点出发,要求沿途走过所有的线段,最终到达\((n,n)\)点,且所走的路程长度要尽......