首页 > 其他分享 >[ABC274E] Booster 题解

[ABC274E] Booster 题解

时间:2023-03-05 12:56:26浏览次数:57  
标签:return ABC274E int 题解 ll ret Booster void define

[ABC274E] Booster Solution

目录

更好的阅读体验戳此进入

题面

在经典的 TSP 问题基础上存在初始速度 $ 1 $,增加 $ m $ 个补给点,经过后会使速度变为原来的 $ 2 $ 倍,最小化时间,求最小值。

Solution

提供一个不太需要动脑但码量略大的思路。

考虑令 $ dp(i, j, k) $ 表示二进制下城镇状态为 $ i $,补给点状态为 $ j $,最后位于点 $ k $ 的最小时间,转移的时候枚举 $ i, j, k $ 再枚举从哪个点而来即可,需要分类讨论从普通点转移还是补给点,以及转移到了普通点还是补给点,对于速率直接使用 __builtin_popcount(j) 计算即可。

同时需要注意计算过程中最多只能使用 long double,使用 __float128 的话会存在约 $ 40 $ 倍常数导致 $ \texttt{TLE} $。

Code

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>

#define PI M_PI
#define E M_E
#define npt nullptr
#define SON i->to
#define OPNEW void* operator new(size_t)
#define ROPNEW void* Edge::operator new(size_t){static Edge* P = ed; return P++;}
#define ROPNEW_NODE void* Node::operator new(size_t){static Node* P = nd; return P++;}

using namespace std;

mt19937 rnd(random_device{}());
int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
bool rnddd(int x){return rndd(1, 100) <= x;}

typedef unsigned int uint;
typedef unsigned long long unll;
typedef long long ll;
typedef long double ld;

#define INFLD (ld)(1e12)

template < typename T = int >
inline T read(void);

int N, M;
pair < ll, ll > town[15], sup[8];
ld dp[4500][40][18];
ld ans(INFLD);

ld CalDis(pair < ll, ll > A, pair < ll, ll > B){
    return sqrt((ld)((A.first - B.first) * (A.first - B.first) + (A.second - B.second) * (A.second - B.second)));
}

int main(){
    for(int i = 0; i <= 4400; ++i)for(int j = 0; j <= 38; ++j)for(int k = 0; k <= 17; ++k)dp[i][j][k] = INFLD;
    N = read(), M = read();
    for(int i = 1; i <= N; ++i)town[i].first = read(), town[i].second = read();
    for(int i = 1; i <= M; ++i)sup[i].first = read(), sup[i].second = read();
    dp[0][0][0] = 0;
    int SmxN = (1 << N) - 1, SmxM = (1 << M) - 1;
    for(int i = 0; i <= SmxN; ++i)
        for(int j = 0; j <= SmxM; ++j){
            ll rate = 1 << __builtin_popcount(j);
            for(int k = 1; k <= N; ++k)
                if(!(i & (1 << (k - 1)))){
                    for(int pos = 0; pos <= N; ++pos)
                        if(dp[i][j][pos] < INFLD)
                            dp[i | (1 << (k - 1))][j][k] = min(dp[i | (1 << (k - 1))][j][k], dp[i][j][pos] + CalDis(town[pos], town[k]) / (ld)rate);
                    for(int pos = N + 1; pos <= N + M; ++pos)
                        if(dp[i][j][pos] < INFLD)
                            dp[i | (1 << (k - 1))][j][k] = min(dp[i | (1 << (k - 1))][j][k], dp[i][j][pos] + CalDis(sup[pos - N], town[k]) / (ld)rate);
                }
            for(int k = 1; k <= M; ++k)
                if(!(j & (1 << (k - 1)))){
                    for(int pos = 0; pos <= N; ++pos)
                        if(dp[i][j][pos] < INFLD)
                            dp[i][j | (1 << (k - 1))][N + k] = min(dp[i][j | (1 << (k - 1))][N + k], dp[i][j][pos] + CalDis(town[pos], sup[k]) / (ld)rate);
                    for(int pos = N + 1; pos <= N + M; ++pos)
                        if(dp[i][j][pos] < INFLD)
                            dp[i][j | (1 << (k - 1))][N + k] = min(dp[i][j | (1 << (k - 1))][N + k], dp[i][j][pos] + CalDis(sup[pos - N], sup[k]) / (ld)rate);
                }
        }
    for(int j = 0; j <= SmxM; ++j){
        ll rate = 1 << __builtin_popcount(j);
        for(int k = 1; k <= N + M; ++k)
            if(dp[SmxN][j][k] < INFLD)
                ans = min(ans, dp[SmxN][j][k] + CalDis(k <= N ? town[k] : sup[k - N], town[0]) / (ld)rate);
    }printf("%.8Lf\n", ans);
    fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
    return 0;
}

template < typename T >
inline T read(void){
    T ret(0);
    int flag(1);
    char c = getchar();
    while(c != '-' && !isdigit(c))c = getchar();
    if(c == '-')flag = -1, c = getchar();
    while(isdigit(c)){
        ret *= 10;
        ret += int(c - '0');
        c = getchar();
    }
    ret *= flag;
    return ret;
}

UPD

update-2023_02_28 初稿

标签:return,ABC274E,int,题解,ll,ret,Booster,void,define
From: https://www.cnblogs.com/tsawke/p/17180252.html

相关文章

  • 题解:【ABC292F】 Regular Triangle Inside a Rectangle
    题目链接不妨设\(a\leb\)。显然当三角形三个点都在矩形边上的时候可以得到答案。通过手玩我们可以发现,当正方形推广到矩形的过程中,我们将一边拉长,三角形就可以不断往......
  • 题解 CF1406D【Three Sequences】
    看错题了,我很生气。problemYouaregivenasequenceof$n$integers$a_1,a_2,\ldots,a_n$.Youhavetoconstructtwosequencesofintegers$b$and$c......
  • LeetCode 29. Divide Two Integers 题解教程 All In One
    LeetCode29.DivideTwoIntegers题解教程AllInOnehttps://leetcode.com/problems/divide-two-integers/description///functiondivide(dividend:number,divis......
  • AGC051E[Middle Point] 题解
    条件转化我们记:\[M=\{x|x=\frac{a}{2^b},a,b\in\mathbb{Z}\}\\M^*=\{x|x\inM,x\ge0\}\]令下文向量均为二维向量,记给定点集为\({\vec{p_n}}\)那么原题即为求满足\(......
  • Java Swing项目使用Idea UI Designer设计插件无法启动问题解决方案
    起因最近整理一下以前写的swing项目,结果发现跑不起来了,具体表现为与视图表绑定的Java类的各属性为NULL(插件没有初始化绑定的类对象),导致项目无法启动。(报空指针异常)问题排......
  • CF1789D Serval and Shift-Shift-Shift 题解
    题目链接题目分析首先,看到题目中的左移右移之后再异或,我们自然可以想到在移动的过程中字符串的一段前缀和后缀不会改变,考虑通过这个性质逐位还原。因为异或0不会改变......
  • 题解 P3455 [POI2007]ZAP-Queries
    题目link是莫比乌斯函数还是莫比乌斯反演捏?感觉好多所谓“莫比乌斯反演”题只要拿\(\mu\)性质给暴力替换一下就能做出来了,比如这题qwq答案是这个式子:\(\sum\limits_{......
  • 萌新也能看懂的 Golang 题解(一)
    写在前面关于“模拟题”和“算法题”及主观难度评价第一批1791.设备编号(模拟)1792.服务器集群网络延时(排序、数学)1793.给定差值的组合(哈希表)1787.最长元音子串(模......
  • 萌新也能看懂的 Golang 题解(二)
    第二批1807.矩阵转置(数学)难度:简单;主观评价:简单。简单模拟题+数学题(判断完全平方数)。先判断矩阵长度是否为完全平方数(开根号然后自身相乘,判断和开根号之前的数是否一致......
  • 萌新也能看懂的 Golang 题解(三)
    第三批1822.电话拦截(模拟、排序)难度:中等;主观评价:简单。sort.Slice() 应用题,重点在于通配符的判断和如何设计数据结构保证最后能按呼叫顺序返回通话记录。对于没有通......