题目大意:有一间披萨店,要送n个披萨去不同的地方
现在给出每个位置之间的距离,每个位置都可以重复经过,问送完所有披萨再回到店里需要走的最短距离是多少
解题思路:这题的话,有两个状态,一个是现所在地点,另一个是已经经过的地点,所以dp数组是二维的
设dp[i][j]为现所在地为i,经过的城市的状态为j的最短路线
那么dp[i][state | (1 << i)] = min(dp[i][state | (1 << i)], dp[j][state] + g[j][i])
。。。这题我竟然用了队列去更新dp,也是醉了
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define N 15
#define maxn 1050
#define INF 0x3f3f3f3f
using namespace std;
struct DP{
int num, state;
}start;
int n, g[N][N];
int dp[N][maxn];
void init(){
int t;
for(int i = 0; i < n; i++)
for(int j = 0; j < n ; j++) {
scanf("%d", &t);
g[i][j] = t;
}
memset(dp, 0x3f, sizeof(dp));
start.num = 0;
start.state = 1;
dp[0][1] = 0;
}
int solve() {
queue<DP> q;
q.push(start);
while(!q.empty()) {
DP t = q.front();
q.pop();
for(int i = 0; i < n; i++) {
if(i == t.num)
continue;
if(dp[i][t.state | (1 << i)] > dp[t.num][t.state] + g[t.num][i]) {
dp[i][t.state | (1 << i)] = dp[t.num][t.state] + g[t.num][i];
DP tt;
tt.num = i;
tt.state = (t.state) | (1 << i);
q.push(tt);
}
}
}
return dp[0][(1 << n) - 1];
}
int main() {
while(scanf("%d", &n) != EOF && n) {
n++;
init();
printf("%d\n", solve());
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-10 10:20:06