• 【洛谷 1171】售货员的难题


    题目描述

    某乡有nn个村庄(1<n le 201<n20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)s(0<s<1000)是已知的,且AA村到BB村与BB村到AA村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为11,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。

    输入格式

    村庄数nn和各村之间的路程(均是整数)。

    输出格式

    最短的路程。

    输入输出样例

    输入 #1
    3
    0 2 1
    1 0 2
    2 1 0
    输出 #1
    3

    说明/提示

    输入解释

    33 {村庄数}

    0 2 1021 {村庄11到各村的路程}

    1 0 2102 {村庄22到各村的路程}

    2 1 0210 {村庄33到各村的路程}

    题解:我一开始还以为是最短路,后来仔细一看原来是DP

              如果考场的话我会先写全排列拿部分分,再慢慢写状压DP

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int oo=0x3f3f3f3f;
    int ans=oo,n,a[22][22],f[1100011][21];
    int main(){
        freopen("1171.in","r",stdin);
        freopen("1171.out","w",stdout);
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                scanf("%d",&a[i][j]);
        memset(f,0x3f,sizeof(f));
        f[1][0]=0;
        int mx=1<<n;
        for(int s=0;s<mx;s++){
            for(int i=0;i<n;i++){
                if(f[s][i]==oo) continue;//i位为1才可推过来 
                for(int j=0;j<n;j++){
                    if(((s>>j)&1)==0){//j位为0 
                        int now=s|(1<<j);
                        f[now][j]=min(f[now][j],f[s][i]+a[i][j]);
                    }
                }
            }
        }
        for(int i=0;i<n;i++)
            ans=min(ans,f[(1<<n)-1][i]+a[i][0]);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    处理在finally中出现的异常(Java)
    【转】alt和title属性的区别及应用
    IE6下兼容CSS属性minheight的解决办法
    javascript中判断字符串是否以指定字符串开始或结尾
    IE6兼容改造中的反思
    字符操作函数
    魔术公式
    抽象类和纯虚函数
    悬空指针
    重载
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/13916200.html
Copyright © 2020-2023  润新知