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复杂度的话,就算我会估计也不知道用什么算法,先搁置这个问题.

posted @ 2020-11-29 14:29  goverclock  阅读(126)  评论(0编辑  收藏  举报