首页 > 其他分享 >AtCoder ABC 270 题解(D-F)

AtCoder ABC 270 题解(D-F)

时间:2022-09-27 13:44:23浏览次数:91  
标签:AtCoder const int 题解 ll mid 270 fa 苹果

AtCoder ABC 270 题解(D-F)

D - Stones(博弈DP)

题目:

​ 现在有一堆石子,一个序列a表示每次可以从石头里拿走多少个石子。当无法再拿出石头的时候,游戏结束。两边都以最佳策略游玩,请问先手者最多能拿走几个石子。

思路:

​ 对于这种两边都采取最佳策略的最优解问题,我们可以很轻易的想到博弈DP的模型。通过记忆化搜索,枚举玩家A拿的所有情况,分割成子问题,取最优解即可。因为对手B也会采取最佳策略,所以减去B拿的最优解就是A所得的最优解。

\[f[u] = max\{(f[u],\; a[i] + (u - a[i]) - f[u - a[i]]), \; a[i] \le u \}; \]

实现:

​ 建议使用记忆化搜索实现。

int n, k;
int a[105];
int f[10005];
 
int dfs(int u)
{
    if(f[u])    return f[u];
    f[u] = 0;
    for(int i = 1; i <= k; i ++)
    {
        if(a[i] > u)    break;
        f[u] = max(f[u], u - dfs(u - a[i]));
    }
    return f[u];
}
 
void solve()
{
    cin >> n >> k;
    for(int i = 1; i <= k; i ++)
        cin >> a[i];
    sort(a + 1, a + k + 1);
    
    cout << dfs(n) << '\n';
}

E - Apple Baskets on Circle(二分)

题目:

​ 有一圈苹果框,每个框里都有若干苹果(\(x=1e18\)),现在按顺序循环拿走k个苹果,自动跳过没有苹果的框, 请问最后每个框里还有多少个苹果。

思路:

​ 可以想到用二分答案来实现,二分拿苹果的轮数,没有就自动跳过,当拿走的苹果数量<=k,即合法。有可能二分的轮数中拿走的苹果会小于k,此时易证最多还需要一轮可以拿走k个苹果。

实现:

const int N = 100005;
int n;
ll k;
ll a[N];
 
bool check(ll mid)
{
    ll res = 0;
    for(int i = 1; i <= n; i ++)
        res += min(mid, a[i]);
    return res <= k;
}
 
void solve()
{
    cin >> n >> k;
    for(int i = 1; i <= n; i ++)
        cin >> a[i];
 
    ll l = 0, r = 1e12;
    while(l < r)
    {
        ll mid = (l + r + 1) / 2;
        if(check(mid))
            l = mid;
        else
            r = mid - 1;
    }
    
    ll m = k;
    for(int i = 1; i <= n; i ++)
    {
        ll mn = min(l, a[i]);
        a[i] -= mn;
        m -= mn;
    }
        
    for(int i = 1; i <= n && m; i ++)
        if(a[i] >= 1ll)   a[i] --, m --;
    
    for(int i = 1; i <= n; i ++)
        cout << a[i] << ' ';
}

F - Transportation(MST 建图思维)

题目:

​ 给你一张n个点,给了三种联通的方式。1:给出m条边,链接a,b,边权为w。2:对于城市\(i\),花费\(x_i\)可在该城市建立机场,所有有机场的城市相互可达。3:对于城市\(i\),花费\(y_i\)可在该城市建立海湾,所有有海湾的城市相互可达。 请问使图联通的最小花费是多少。

思路:

​ 显然是在问最小生成树,但是需要通过超级源点的思想来特殊处理一下飞机和海港的情况。对于不同的情况分类讨论,跑4次最小生成树即可。

实现:

const int N = 200005;
int x[N], y[N];
int fa[N];
const ll inf = 3e18;

struct Edge {
    int a, b, w;
    bool operator< (const Edge &t) const {
        return w < t.w;
    }
}e[N], g[N * 3];

int fd(int x)
{
    if(x != fa[x])  fa[x] = fd(fa[x]);
    return fa[x];
}

ll Kruskal(int n, int m) //n个点,m条边
{
    sort(g + 1, g + m + 1);
    for(int i = 1; i <= n; i ++)    fa[i] = i;

    ll res = 0;
    int cnt = 0;
    for(int i = 1; i <= m; i ++)
    {
        auto t = g[i];
        int a = t.a, b = t.b, w = t.w;
        int t1 = fd(a), t2 = fd(b);
        
        if(t1 != t2)
        {
            fa[t2] = t1;
            res += w;
            cnt ++;
        }
    }
    if(cnt == n - 1)    return res;
    return inf;
}

int main()
{
    int n, m;
    ll res = inf;
    cin >> n >> m;
    for(int i = 1; i <= n; i ++)
        cin >> x[i];
    for(int i = 1; i <= n; i ++)
        cin >> y[i];
    
    for(int i = 1; i <= m; i ++) //m条边
        cin >> e[i].a >> e[i].b >> e[i].w;
        
    for(int i = 1; i <= m; i ++)
        g[i] = e[i];
    res = min(res, Kruskal(n, m));
    
    for(int i = 1; i <= m; i ++)
        g[i] = e[i];
    for(int i = 1; i <= n; i ++) //飞机
        g[i + m] = {i, n + 1, x[i]};
    res = min(res, Kruskal(n + 1, m + n));
    
    for(int i = 1; i <= m; i ++)
        g[i] = e[i];
    for(int i = 1; i <= n; i ++) //海
        g[i + m] = {i, n + 1, y[i]};
    res = min(res, Kruskal(n + 1, m + n));
    
    for(int i = 1; i <= m; i ++)
        g[i] = e[i];
    for(int i = 1; i <= n; i ++) 
        g[i + m] = {i, n + 1, x[i]};
    for(int i = 1; i <= n; i ++)
        g[i + m + n] = {i, n + 2, y[i]}; //飞机和海
    res = min(res, Kruskal(n + 2, m + n + n));

    cout << res << '\n';
}

标签:AtCoder,const,int,题解,ll,mid,270,fa,苹果
From: https://www.cnblogs.com/DM11/p/16734283.html

相关文章

  • AtCoder Beginner Contest 256
    AtCoder五十连练第二练AtCoderBeginnerContest256D-UnionofInterval给定\(N\)个左闭右开的区间,求这些区间的并集。数据范围:\(1\leN\le2\times10^5\)......
  • AtCoder Beginner Contest 270 G,Ex
    y1s1,G和Ex在推等比数列式子上是相似的。G前置知识:BSGS(其实就是根号讨论)首先我们展开这个递归式:\[X_{i}\equivA^{i}S+\sum_{j=0}^{i-1}A^jB\modP\]感觉第一项有......
  • 题解【CF1436E Complicated Computations】
    CF1436EComplicatedComputations解题报告。不一定更好的阅读体验。对于一个数\(x\),考虑什么条件\(x\)可以作为答案。首先要满足\(\forally\in[1,x)\),\(y\)......
  • SpringBoot+Mybatis-Plus 数据表字段是关键字的问题解决
    如果字段名是关键字,用mybatisplus时会报以下错误:badSQLgrammar[];nestedexceptionisjava.sql.BatchUpdateException:ORA-01747:user.table.column,table.column......
  • 力扣算法第1题--两数之和(暴力题解&优化题解)
    两数之和题目描述:给定一个整数数组nums 和一个整数目标值target,请你在该数组中找出和为目标值target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输......
  • P2044 随机数生成器 题解
    这么标准的不动点居然只有一篇不动点题解?而且唯一的不动点题解关于不动点的描述还是错的?所以,来写一篇题解讲讲,MO中是怎么弄这种一阶线性递推式的。单个数,虽然省常数,却......
  • Atcoder试题乱做 Part2
    感受下来,思维难度有参差,所以还是可以做的,虽然有的题和中国赛题差距有点大,但是无伤大雅?新的\(\text{Part}\)我要自己做出来更多题!\(\text{[AGC014D]Blackan......
  • Atcoder试题乱做 Part4
    时光怎不经一生浮浮沉沉已半生一壶浊酒欲随风一步一瞥似惊鸿情字要如何追问一指兰花为谁挽留\(\text{[ARC147D]SetsScores}\)\(\color{green}{\text{[EASY]}}\)......
  • Atcoder试题乱做 Part3
    最后一年了,一年不到,为了可爱的学长们,为了自己,要拼命了啊.\(\text{[AGC048D]PockyGame}\)\(\color{green}{\text{[EASY]}}\)怎么这都做不出来,废物啊.显然石......
  • P6835 [Cnoi2020]线形生物 题解
    通过这道题可以看出来pz根本不会期望考虑期望线性性质,设\(E_{x\toy}\)表示从\(x\)走到\(y\)的期望步数,那么有\(E_{1\ton+1}=\sum_{i=1}^nE_{i\toi+1}\),因此考......