--- 这里是 cjiaw 的小窝(●'◡'●) ---

正在玩命加载中......

洛谷__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;
}

 

posted @ 2025-10-21 17:04  wwjjw  阅读(13)  评论(0)    收藏  举报