2016级算法期末模拟练习赛-C.AlvinZH的青春记忆II

1084 AlvinZH的青春记忆II

思路

中等题,二分。

简化题意,一列数字,每秒会自动-1,特殊操作可以使一个数在1s内-k,问这些数都减至0需要多久。

答案肯定在[1,xMax]之间,采用二分的方法找到最小时间。

如何判断一个时间值是否符合要求呢?对于≤mid的数,自然消减就好,对于>mid的数,需要特殊操作,设特殊操作次数为s,则有 \(k*s + (mid-s) = Xi\),解得 \(s = (X[i]-mid) / (k-1)\)。

分析

注意三个问题,

第一,除0问题,k-1可能为0,需要提前特判,如果k==1,那个和自然递减没有差别,答案直接输出xMax。

第二,式子中有可能会出现小数,如何处理?向上取整!\(s = ceil(1.0*(X[i]-mid) / (k-1))\)。

第三,计算过程中s需要多次叠加,有可能会超过int范围,需要使用long long。

参考代码

//
// Created by AlvinZH on 2017/12/9.
// Copyright (c) AlvinZH. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int n, k;
int X[100000+10];
int Xmax;

int main ()
{
    while(~scanf("%d %d", &n, &k))
    {
        Xmax = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &X[i]);
            if(X[i] > Xmax)
                Xmax = X[i];
        }
        if(k == 1)
        {
            printf("%d\n", Xmax);
            continue;
        }

        int ans = 0;
        int l = 1, r = Xmax, mid;
        while (r >= l)
        {
            mid = (l+r)/2;

            long long cnt = 0;
            for (int i = 0; i < n; i++)
            {
                if(X[i] > mid)
                {
                    long long s = ceil(1.0*(X[i]-mid) / (k-1));
                    cnt += s;
                }
            }
            if (cnt > mid)
                l = mid+1;
            else
                r = mid-1, ans = mid;
        }
        printf ("%d\n", ans);
    }
}

原文地址:https://www.cnblogs.com/AlvinZH/p/8137719.html

时间: 2024-11-08 09:08:35

2016级算法期末模拟练习赛-C.AlvinZH的青春记忆II的相关文章

2016级算法期末模拟练习赛-B.AlvinZH的青春记忆I

1083 AlvinZH的青春记忆I 思路 中等题,动态规划. 简化题意,一个环上取数,数不可相邻,取取得数之和最大值. 环不好表示,可以解开变成一列数,那么答案应为下列两种情况较大者. ①:取第一个点,可取得最大价值为宝物[1,n-1]的最大价值. ②:不取第一个点,可取得最大价值为宝物[2,n]的最大价值. 动态规划,状态转移方程:\(dp[i] = max(dp[i-1], dp[i - 2] + V[i])\) 分析 时间复杂度:\(O(n)\). 参考代码 // // Created

2016级算法期末模拟练习赛-D.AlvinZH的序列问题

1111 AlvinZH的序列问题 思路 中等题,动态规划. 简化题意,. 坑点一:二维int数组MLE,明显会超过内存限制,由于\(n\)最大为1e4,那么我们的dp数组最大也是1e4,考虑使用short int. 坑点而:被题目开始的子序列描述误导,题目没有要求等差数列中数字顺序和输入顺序一致,所以可以先将数组排序. dp[i][j]:以A[i].A[j]开头的等差数列(可保证i<j).初始化值为2. 状态转移:固定j,i与k分别向两边扩展,当2*A[j]=A[i]+A[k]时,说明A[i]

2016级算法期末模拟练习赛-A.wuli51和京导的毕业旅行

1063 wuli51和京导的毕业旅行 思路 中等题,二分+贪心. 简化题意,将m+1个数字分成n份,ans为这n段中每段数字和的最大值,求ans最小值及其方案. 对于这种求最小的最大值,最常用的方法是二分.答案一定在[0,sum]之间,通过判断是否符合要求可以求得ans.在本题中,ans一定是整数,所以二分过程中left.mid.right也是整数. 如何判断是否符合要求?对于某一mid值,遍历一次露营地距离数组,通过贪心,总是使一天内的行程尽可能接近mid,但不可超过mid.若是加上某一露营

A1-2017级算法上机第一次练习赛 P ModricWang&#39;s Number Theory II

题目描述 ModricWang has found a list containing n numbers. He calls a list bad if and only if it is not empty and gcd (see notes section for more information) of numbers in the list is 1. ModricWang can perform two types of operations: Choose a number an

A1-2017级算法第一次上机练习赛 C AlvinZH去图书馆

题目描述 AlvinZH最近在看<冰与火之歌>系列,这天,他又看完了一本书,于是决定去图书馆再借一本.大家知道,在去图书馆的路上,有一条"扯蛋路".大概是这个样子的(秀一波拍照技术): AlvinZH从第一块石砖出发,接下来他可以走到第二块石砖或第三块石砖,有时候走的很不爽,甚至可以直接跨过两个石砖,到达第四块石砖,但是不能连续两次这种操作,因为这样...对身体不好.现在假设有一条含n块石砖的小路,请你计算出AlvinZH从第一块石砖出发有多少种安全的走法. 输入 输入将由

2016级算法第三次上机-C.AlvinZH的奇幻猜想——三次方

905 AlvinZH的奇幻猜想--三次方 思路 中等题.题意简单,题目说得简单,把一个数分成多个立方数的和,问最小立方数个数. 脑子转得快的马上想到贪心,从最近的三次方数往下减,反正有1^3在最后撑着保证减完.不好意思这是错的,因为1,27,64,125...等立方数之间并不是倍数关系,不能构成贪心策略.举个反例:96=64+8+8+8+8=64+27+1+1+1+1+1,答案明显是5,而贪心会算到7. 既然不是贪心,那就是DP了,没毛病.先讲一下常规做法吧,是这样想的:相当于把一个数化成几份

2016级算法第六次上机-C.AlvinZH的学霸养成记II

1032 AlvinZH的学霸养成记II 思路 中等题,贪心. 所有课程按照DDL的大小来排序. 维护一个当前时间curTime,初始为0. 遍历课程,curTime加上此课程持续时间d,如果这时curTime大于此课程DDL,表示无法学习此课程,但是我们不减去此课程,而是减去用时最长的那门课程(优先队列队首,课时最长). 贪心: 假设当前课程为B,被替换课程为A,则有A.d≥B.d,A.e≤B.e.既然curTime+A.d≤A.e,那么curTime+B.d≤B.e绝对成立,保证了B的合法性

2016级算法第三次上机-G.Winter is coming

904 Winter is coming 思路 难题.首先简化问题, \(n\) 个0与 \(m\) 个1排成一列,连续的0不能超过x个,连续的1不能超过y个,求排列方法数. 显然会想到这是动态规划.最快想到的方法是 \(dp[i][j][x][y]\) 表示已经有i个北境兵j个野人参与排列,且末尾有x个连续北境士兵或y个连续野人士兵的方案数.这方法显然是正确的,但是光是 \(dp[200][200][10][10]\) 数组已经十分接近本题内存限制了,保证MLE.状态转移方法是大模拟,四层fo

2016级算法第六次上机-A.Bamboo之寻找小金刚

Bamboo之寻找小金刚 分析 可以抽象为许多连续线段,分别计数左拐和右拐的个数.考察叉积的基础应用. 假设ABC三点构成一个夹角∠ABC,B就是拐点,AC是辅助形成夹角.考虑线段AB和BC形成的向量 sin∠ABC= (AB * BC)/|AB|*|BC| 两个向量的叉乘除以它们的模 所以叉乘可以判断夹角是否大于180°从而确定转向.当然叉积是有方向的,可以自己选择哪条边在前,只要标准统一即可.每三个点组成一组,遍历,分别计数左拐数和右拐数.具体叉积相关操作可以看<算法导论> 注意 常见的一