解题报告:luogu P1433 吃奶酪

题目链接:P1433 吃奶酪
我感觉可以改成:【模板】TSP问题(商旅问题) 了。
爆搜\(T\)一个点,考虑状压\(dp\)(还是爆搜)。
我们用\(dp[i][j]\)表示现在是\(i\)状态,站在了\(j\)点。
那什么是状态呢? 我们用一个零一串表示每一点有无被走过(\(0\)是没走过,\(1\)是已走过),那么转移方程就是:
\[dp[i][j]=min(dp[i][j],dp[i\&((1<<n)-1-(1<<(j-1)))][k]+dis[j][k])\]
好好理解下,就是吃掉走过的每一点。
复杂度就是\(O(2^nn^2)\),对于\(n\leqslant15\)的数据,上界为\(7372800\),可以通过本题,还跑得挺快。

\(Code\):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
struct node
{
    double x,y;
}a[17];
int n;
double dp[65005][17];
double minn=21247483647;
double dis(node m,node n){return sqrt((m.x-n.x)*(m.x-n.x)+(m.y-n.y)*(m.y-n.y));}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=(1<<15);i++)
    {
        for(int j=1;j<=15;j++) dp[i][j]=214748364;
    }
    for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    for(int i=1;i<=n;i++) dp[1<<(i-1)][i]=0;//从零开始扫会RE
    for(int i=1;i<=(1<<n)-1;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(!(1<<(j-1)&i)) continue;
            for(int k=1;k<=n;k++)
            {
                if(j==k) continue;
                if(!(1<<(k-1)&i)) continue;
                dp[i][j]=min(dp[i][j],dp[i&((1<<n)-1-(1<<(j-1)))][k]+dis(a[j],a[k]));
            }
        }
    }
    node e;
    e.x=e.y=0;
    for(int i=1;i<=n;i++) minn=min(minn,dp[(1<<n)-1][i]+dis(a[i],e));
    //注意这里把原点算上
    printf("%.2lf\n",minn);
    return 0;
}

转移方程有简单点的写法:
\[dp[i][j]=min(dp[i][j],dp[i-(1<<(j-1))][k]+dis[j][k])\]
被骗了吧......

原文地址:https://www.cnblogs.com/tlx-blog/p/12344033.html

时间: 2024-10-19 02:28:06

解题报告:luogu P1433 吃奶酪的相关文章

luogu P1433 吃奶酪

原题链接:https://www.luogu.org/problem/show?pid=1433 虽然是一道思维难度不大的DFS,但是这其中比较重要的是可行性剪枝(这是本蒟蒻做的第一道剪枝) 本题的优化点有不少:预处理两点之间的距离,用邻接矩阵存储,搜索时直接调用即可. 当目前走到的距离已经超过现有的最小值,那么就无需继续搜索下去,直接返回即可. (那些register 之类的,都是因为写了个死循环TLE了以为常数问题加的...) #include<cstdio> #include<cm

洛谷OJ P1433 吃奶酪 解题报告

洛谷OJ P1433 吃奶酪 解题报告 by MedalPluS 题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入描述 第一行一个数n  (n<=15)接下来每行2个实数,表示第i块奶酪的坐标.两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 输出描述 一个数,表示要跑的最少距离,保留2位小数. 分析 这题很明显就是一个搜索题,枚举一下1_n的全排列,然后从0开始,按照排列一个一个算,时间

洛古——P1433 吃奶酪

https://www.luogu.org/problem/show?pid=1433 题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块奶酪的坐标. 两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 输出格式: 一个数,表示要跑的最少距离,保留2位小数. 输入输出样例 输入样例#1: 4 1 1 1 -1

P1433 吃奶酪

题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块奶酪的坐标. 两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 输出格式: 一个数,表示要跑的最少距离,保留2位小数. 输入输出样例 输入样例#1: 4 1 1 1 -1 -1 1 -1 -1 输出样例#1: 7.41 代码: #include"stda

洛谷 P1433 吃奶酪 Label:dfs &amp;&amp; 剪枝Ex

题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块奶酪的坐标. 两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 输出格式: 一个数,表示要跑的最少距离,保留2位小数. 输入输出样例 输入样例#1: 4 1 1 1 -1 -1 1 -1 -1 输出样例#1: 7.41 代码 1 #include<iostr

洛谷 P1433 吃奶酪

题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块奶酪的坐标. 两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 输出格式: 一个数,表示要跑的最少距离,保留2位小数. 输入输出样例 输入样例#1: 4 1 1 1 -1 -1 1 -1 -1 输出样例#1: 7.41 dfs 屠龙宝刀点击就送 #includ

P1433 吃奶酪 回溯法

题目描述 房间里放着n块奶酪.一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0)点处. 输入输出格式 输入格式: 第一行一个数n (n<=15) 接下来每行2个实数,表示第i块奶酪的坐标. 两点之间的距离公式=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 输出格式: 一个数,表示要跑的最少距离,保留2位小数. 输入输出样例 输入样例#1: 复制 4 1 1 1 -1 -1 1 -1 -1 输出样例#1: 复制 7.41 一开始回溯法显然超时然后加了

leetCode解题报告5道题(七)

先送上亚马逊传送门:<黑客与画家>:硅谷创业之父 Paul Graham 文集 再送上一个思维导图: 最好的办法就是自己创业或者加入创业公司 一个命题 命题 创业是一个压缩的过程,所有工作压缩成短短几年. 你不再是低强度的工作四十年,而是以极限强度工作四年 举例解释 一个优秀的黑客去除各种障碍,工作效率可以是在公司时的36倍. 假设他年薪8万美元,那么一个勤奋工作,摆脱杂事干扰的聪明黑客, 他的工作相当于年薪200万美元的价值 这里说的是极限情况,休闲时间为0,工作强度足以危害到健康. 守恒定

POJ_1007:DNA Sorting解题报告

[大致题意]排列多个DNA序列,按照每个序列的"有序程度".如果一个序列已经按照字母顺序排好了,那么这个序列有序程度最高,如AACCGGTT.反之,如果一个序列越无序,那么它的有序程度越低,如TGTCAA. [解题思路]计算每个序列的"逆序数",即反序字母对的个数,如ATGC的逆序数是3,因为TG,TC,GC都是逆序的.然后按照每个序列的逆序数排序,逆序数越大说明这个序列越无序. #include <iostream> #include <algo