zoukankan      html  css  js  c++  java
  • 吃奶酪

    题目:

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

    4
    1 1
    1 -1
    -1 1
    -1 -1
    答案是7.41

    设dp[i][j]是状态为i处在第j个点的最小路径
    那么对于一个确定的状态而言,我可以扫描它,把所有为1的点找出来
    然后抠掉某一个1,得到的新状态就是i的上一个状态
    我们可以枚举所有状态中的1,除了抠掉的那个
    因为我们是要找一个点走到抠掉的那个点,使得路径最小。
    #include <bits/stdc++.h>
    using namespace std;
    int n;
    double x[17],y[17],dp[1<<15][16];
    double ji(int q,int w){
        return sqrt((x[q]-x[w])*(x[q]-x[w])+(y[q]-y[w])*(y[q]-y[w]));
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)    cin>>x[i]>>y[i];
        for(int i=0;i<(1<<15);i++)
        for(int j=0;j<=15;j++)
        dp[i][j]=1e18;//double类型不能用memset 
        for(int i=1;i<(1<<n);i++)
        {
            for(int j=0;j<n;j++)
            {
                if(i&(1<<j))//这个位置有1 
                {
                    if((1<<j)==i)
                    {
                        dp[i][j]=ji(0,j+1);//刚从原点出发
                        continue;
                    }
                    else
                    {
                        for(int k=0;k<n;k++)
                        {
                            if(k!=j&&((1<<k)&i))
                                dp[i][j]=min(dp[i][j],dp[i-(1<<j)][k]+ji(k+1,j+1));
                        }
                    }
                }
            }
        }
        double inf=999999999;
        for(int i=0;i<=n-1;i++)    inf=min(inf,dp[(1<<n)-1][i]);
        printf("%.2lf",inf);
    }

     19.3.17自己写的版本(下标从1起)

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    double dp[1<<15][20];
    double x[29],y[29],dis[20][20];
    double d(int l,int r){
        return sqrt((x[l]-x[r])*(x[l]-x[r])+(y[l]-y[r])*(y[l]-y[r]));
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)    cin>>x[i]>>y[i];
        for(int i=0;i<(1<<n);i++)for(int j=0;j<=19;j++)    dp[i][j]=99999999;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        dis[i][j]=dis[j][i]=d(i,j);
        for(int i=1;i<=n;i++)
            dp[1<<(i-1)][i]=d(i,0);
        for(int i=1;i<(1<<n);i++)//枚举当前状态 
        {
            for(int j=1;j<=n;j++)//枚举出发点    
            {
                if(i&(1<<(j-1)))
                {
                    for(int q=1;q<=n;q++)//枚举上一个状态的位置
                    {
                        if(q==j)    continue;
                        if(i&(1<<(q-1)))
                        {
                            int k=i-(1<<(j-1));//上一行的状态
                            dp[i][j]=min(dp[i][j],dp[k][q]+dis[j][q]);    
                        }    
                    } 
                }
            }
        }
        double ans=99999999;
        for(int i=1;i<=n;i++)
            ans=min(ans,dp[(1<<n)-1][i]);
        printf("%.2lf",ans);
    }
    View Code
  • 相关阅读:
    struts2的execAndWait拦截器
    听说百度网盘可以这样下载文件
    文件下载
    struts2文件上传
    注解实现struts2零配置
    struts2.properties
    拦截器
    curl+个人证书(又叫客户端证书)访问https站点
    Wireshark入门与进阶系列(一)
    Wireshark入门与进阶系列(二)
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12469376.html
Copyright © 2011-2022 走看看