算法设计与分析基础题——售货员的难题

解法代码一:

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

#define INF 0x3f3f3f3f

int n;

int mpt[20][20];

int dp[20][1<<20];

void solve()

{

    int i,j,k,MAX=1<<n;

    memset(dp,INF,sizeof(dp));

    for(i=0;i<n;i++)

    {

        dp[i][1<<i]=mpt[0][i];

    }

    for(j=0;j<MAX;j++)

    {

        for(i=0;i<n;i++)

        {

            if((j&(1<<i))==0) continue;  //注意运算符优先级

            for(k=0;k<n;k++)

            {

                dp[i][j]=min(dp[i][j],dp[k][j&(~(1<<i))]+mpt[k][i]);

            }

        }

    }

    printf("%d\n",dp[0][MAX-1]);

}

int main()

{

    while(scanf("%d",&n)!=EOF)

    {

        for(int i=0;i<n;i++)

        {

            for(int j=0;j<n;j++)

            {

                scanf("%d",&mpt[i][j]);

            }

        }

        solve();

    }

    return 0;

}

///////////////////////////////////////////////////////////

解法代码二:

#include<iostream>

#include<cstdio>

using namespace std;

int n, g[20][20], r[20][20], f[20], ans = 0x7fffffff;

void Dfs(int now, int sum, int dis)

{

    if (dis + r[now][1] >= ans)return; //如果最小距离仍然大于最优解,直接减枝

    if (dis>ans)return;

    if (sum == n)

    {

        ans = min(ans, dis + g[now][1]);

        return;

    }

    for (int i = 1; i <= n; i++)

    if (f[i] == 0)

    {

        f[i] = 1; Dfs(i, sum + 1, dis + g[now][i]); f[i] = 0;

    }

}

int main()

{

    scanf("%d", &n);

    for (int i = 1; i <= n; i++)

    for (int j = 1; j <= n; j++)

        scanf("%d", &g[i][j]), r[i][j] = g[i][j];

    for (int k = 1; k <= n; k++)

    for (int i = 1; i <= n; i++)

    for (int j = 1; j <= n; j++)

        r[i][j] = min(r[i][j], r[i][k] + r[j][k]); //计算两点之间的最小距离

    f[1] = 1;

    Dfs(1, 1, 0);

    printf("%d\n", ans);

    return 0;

}

相关文章:

  • 2022-12-23
  • 2021-10-16
  • 2021-08-03
  • 2022-01-10
  • 2021-10-26
  • 2021-12-04
  • 2021-08-08
猜你喜欢
  • 2022-12-23
  • 2022-01-20
  • 2022-02-01
  • 2021-12-05
  • 2021-07-31
相关资源
相似解决方案