1. 程式人生 > 實用技巧 >P1433 吃乳酪 深度搜索 剪枝 卡時

P1433 吃乳酪 深度搜索 剪枝 卡時

P1433 吃乳酪

生活就像是與TLE鬥智鬥勇.

第一次用卡時.

窮竭搜尋,發現情況不如已有解時剪枝.

比較直白的dfs,所以直接放程式碼,重點是裡面用到的一個技巧.

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;

int n, t;
double ans = 100000000.0;
typedef pair<double
, double> P; P s[20], tmp; bool used[20]; double len(double x1, double y1, double x2, double y2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } void dfs(double x, double y, double sum) { if(++t > 30000000) { int ti = clock(); if(ti >= 940) { printf(
"%.2f\n", ans); exit(0); } } if(sum < ans) { bool bad = true; for(int i = 1; i <= n; i++) if(!used[i]) { bad = false; used[i] = true; dfs(s[i].first, s[i].second, sum + len(s[i].first, s[i].second, x, y)); used[i]
= false; } if(bad) ans = min(ans, sum); } } int main() { cin >> n; for(int i = 1; i <= n; i++) cin >> s[i].first >> s[i].second; dfs(0, 0, 0); printf("%.2f\n", ans); return 0; }

注意到

if(++t > 30000000)
    {
        int ti = clock();
        if(ti >= 940)
        {
            printf("%.2f\n", ans);
            exit(0);
        }
    }

如果沒有這一段也是完全可以執行的,而且在資料較弱的情況下可以達到時限.

但是這時候TLE了一個點,本地測一下大概需要十秒左右(好像更快一點)才有輸出.可以推測這時候接近於發現的解總是比上一個好的情況,也就是剪枝的最壞情況.

如果懶得換演算法的話,就會用到這種不一定會給出正確答案的方法了,卡時.

在你估計快要超時,但是還沒有搜尋完畢,那就直接給出當前發現的最優解,很有可能就是正確答案.

所以說,這是一種不穩定的方法,可能有的題目會防止卡時讓你爆,但是這題就直接AC了.

如果想要估計dfs複雜度的話,就算我會估計也不知道用什麼演算法,先擱置這個問題.