洛谷__P1433 吃奶酪
题目链接:P1433 吃奶酪 - 洛谷
题目大意:
块奶酪。一只小老鼠要把它们都吃掉,老鼠 开始在 点处
求:至少要跑多少距离;
代码:
递归写法:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 16, mod = 998244353;
int n;
double a[N], b[N];
double f[N][1 << N];//走过i个点后,还要走的最小值 -> [走了多少个点][具体了哪些点]
bool st[N];
// 当前节点 深度 从起点走了长度 选的点
double dfs(int u, int dp, double len, int path) {
double res = 1e9;
if (dp == n) return len;//走完n个点返回总长度
if (f[u][path]) return f[u][path] + len;//剩下要走的最小值 + 已走的长度
for (int i = 1; i <= n; i++) {
if (st[i]) continue;
st[i] = true;
double xx = a[i] - a[u];
double yy = b[i] - b[u];
double r = sqrt(xx * xx + yy * yy);//这点与上个点的距离
res = min(res, dfs(i, dp + 1, len + r, path | (1 << i)));
st[i] = false;//回溯
}
f[u][path] = res - len;
return res;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i] >> b[i];
printf("%.2lf", dfs(0, 0, 0, 0));
}
signed main() {
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
普通写法:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 17, mod = 998244353;
int n;
double a[N], b[N];
double f[1 << N][N];
void solve() {
cin >> n;
for (int i = 2; i <= n + 1; i++) cin >> a[i] >> b[i];
for (int i = 0; i <= (1 << n + 1) -1; i++) {
for (int j = 0; j <= n + 1; j++) {
f[i][j] = inf;
}
}
f[1][1] = 0;
for (int st = 1; st <= (1 << n + 1) -1; st++) {
for (int u = 1; u <= n + 1; u++) {
if ((st & (1 << u - 1)) == 0) continue;//走过
double x = a[u], y = b[u];
for (int v = 1; v <= n + 1; v++) {
if (st & (1 << v - 1)) continue;//没走过
double xx = a[v] - x, yy = b[v] - y;
double r = sqrt(xx * xx + yy * yy);
f[st | (1 << v - 1)][v] = min(f[st | (1 << v - 1)][v], f[st][u] + r);
}
}
}
double res = inf;
for (int i = 2; i <= n + 1; i++) {
res = min(res, f[(1 << n + 1) -1][i]);
}
printf("%.2lf", res);
}
signed main() {
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号