文章导航

  • 例题
    • ACW 102. 最佳牛围栏
      • 题面
      • 解析
      • AC代码
    • ACW 113. 特殊排序
      • 题面
      • 解析
      • AC代码
    • LC 410. 分割数组的最大值
      • 题面
      • 解析
      • AC代码:DP
      • AC代码:二分&贪心

例题

ACW 102. 最佳牛围栏

题目链接

题面

农夫约翰的农场由NNN块田地组成,每块地里都有一定数量的牛,其数量不会少于1头,也不会超过2000头。
约翰希望用围栏将一部分连续的田地围起来,并使得围起来的区域内每块地包含的牛的数量的平均值达到最大。
围起区域内至少需要包含 FFF块地,其中FFF会在输入中给出。
在给定条件下,计算围起区域内每块地包含的牛的数量的平均值可能的最大值是多少。

解析

连续区间求平均值问题,使用前缀和加二分法求解
假设长度为FFF的连续区间的平均值为xxx,定义前缀和
s[i]=s[i−1]+a[i]−xs[i]=s[i-1]+a[i]-x s[i]=s[i−1]+a[i]−x
对于当前最小的s[i−F]s[i-F]s[i−F],如果s[i]≥s[i−F]s[i]\geq s[i-F]s[i]≥s[i−F]表示长度为FFF的区间均值至少为xxx,以此构建二分法的判断函数.

AC代码

#include <cstring>
#include <cstdio>
#include <iostream>using namespace std;const int N=100005;
const double EPS=1e-5;
const int d=1000;int n, F;
double a[N], s[N];bool f(double avg){for(int i=1; i<=n; ++i) s[i]=s[i-1]+a[i]-avg; // 计算前缀和double mins=0;for(int k=F; k<=n; ++k){mins=min(mins, s[k-F]);if(s[k]>=mins) return true;}return false;
}int main(){cin>>n>>F;double l=0, r=0;for(int i=1; i<=n; ++i){scanf("%lf", &a[i]);r=max(r, a[i]); // 找到最多牛的田,将牛的数量记为r}while(r-l>EPS){ // 浮点数二分法double mid=(l+r)/2;if(f(mid)) l=mid;else r=mid;}printf("%d\n", (int)(r*d));return 0;
}

ACW 113. 特殊排序

题目链接

题面

有NNN个元素,编号1.2..N1.2..N1.2..N,每一对元素之间的大小关系是确定的,关系具有反对称性,但不具有传递性.
注意:不存在两个元素大小相等的情况。
也就是说,元素的大小关系是NNN个点与N∗(N−1)/2N*(N-1)/2N∗(N−1)/2条有向边构成的任意有向图。
然而,这是一道交互式试题,这些关系不能一次性得知,你必须通过不超过100001000010000次提问来获取信息,每次提问只能了解某两个元素之间的关系.
现在请你把这NNN个元素排成一行,使得每个元素都小于右边与它相邻的元素.
你可以通过我们预设的bool函数compare来获得两个元素之间的大小关系.
例如,编号为a和b的两个元素,如果元素a小于元素b,则compare(a,b)返回true,否则返回false.
将NNN个元素排好序后,把他们的编号以数组的形式输出,如果答案不唯一,则输出任意一个均可.

解析

二分法的交互题

AC代码

// Forward declaration of compare API.
// bool compare(int a, int b);
// return bool means whether a is less than b.class Solution {public:vector<int> specialSort(int N) {vector<int> ans{1}; for(int i=2; i<=N; ++i){int l=0, r=ans.size()-1;while(l<r){ // 二分法定位待插入的位置int mid=l+r+1>>1;if(compare(ans[mid], i)) l=mid;else r=mid-1;}ans.push_back(i);for(int j=ans.size()-2; j>r; --j) swap(ans[j], ans[j+1]); // 将最后的i交换到r+1的位置if(compare(i, ans[r])) swap(ans[r], ans[r+1]); // 如果i是最小的 }return ans;}
};

LC 410. 分割数组的最大值

题目链接

题面

给定一个非负整数数组和一个整数 mmm,你需要将这个数组分成mmm个非空的连续子数组。设计一个算法使得这mmm个子数组各自和的最大值最小。

解析

方法1:使用动态规划求解
定义f[i][j]f[i][j]f[i][j]表示将数组前iii个元素划分为jjj段连续子数组的得到和的最小值,对0∼i−10\sim i-10∼i−1进行枚举(因为不存在空段,所以只要枚举到i−1i-1i−1即可),设前kkk元素被分为j−1j-1j−1段,第k+1k+1k+1个元素到第iii个元素是第jjj段,因此得到状态转移方程,其中s[i]s[i]s[i]表示前缀和.
f[i][j]=min(f[i][j],max⁡(f[k][j−1],s[i]−s[k+1]))f[i][j]=min(f[i][j], \max(f[k][j-1], s[i]-s[k+1])) f[i][j]=min(f[i][j],max(f[k][j−1],s[i]−s[k+1]))
方法2:使用二分法+贪心策略
对子段和的最大值进行枚举,假设当前子段和最大值为sss,如果在此约束下,可以将数组分为≤m\leq m≤m段,则缩小sss继续二分搜索,否则扩大二分,继续进行搜索.

AC代码:DP

typedef long long LL;
class Solution {public:int splitArray(vector<int>& nums, int m) {int n=nums.size();LL f[n+1][m+1];LL s[n+1];memset(f, 0x7f, sizeof f);memset(s, 0x00, sizeof s);for(int i=1; i<=n; ++i) s[i]=s[i-1]+nums[i-1];f[0][0]=0;for(int i=1; i<=n; ++i)for(int j=1; j<=min(i, m); ++j)for(int k=0; k<i; ++k)f[i][j]=min(f[i][j], max(f[k][j-1], s[i]-s[k]));return (int)f[n][m];}
};

AC代码:二分&贪心

typedef long long LL;
class Solution {public:int splitArray(vector<int>& nums, int m) {int n=nums.size();LL s[n+1];memset(s, 0x00, sizeof s);for(int i=1; i<=n; ++i) s[i]=s[i-1]+nums[i-1];function<bool(LL)> f=[&](LL sub){ // 在当前子段和sub的限制下,最少可以分为多少段int cnt=0, j=0;for(int i=1; i<=n-1; ++i){if(s[i]-s[j]<=sub && s[i+1]-s[j]>sub){++cnt;j=i;}}if(s[n]-s[j]<=sub) ++cnt;else return false;return cnt<=m;};LL l=0, r=s[n];while(l<r){LL mid= l+(r-l)/2;if(f(mid)) r=mid;else l=mid+1;}return l;}
};

【ALGO】基础算法(3)相关推荐

  1. 基础算法整理(1)——递归与递推

    程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一 ...

  2. 暑期集训2:ACM基础算法 练习题G:POJ - 1298

    2018学校暑期集训第二天--ACM基础算法 练习题G  --  POJ - 1298 The Hardest Problem Ever Julius Caesar lived in a time o ...

  3. 暑期集训2:ACM基础算法 练习题C:CF-1008A

    2018学校暑期集训第二天--ACM基础算法 练习题A  --   CodeForces - 1008A Romaji Vitya has just started learning Berlanes ...

  4. 暑期集训2:ACM基础算法 练习题B:CF-1008B

    2018学校暑期集训第二天--ACM基础算法 练习题B  --   CodeForces - 1008B Turn the Rectangles There are nn rectangles in ...

  5. 暑期集训2:ACM基础算法 练习题A:CF-1008C

    2018学校暑期集训第二天--ACM基础算法 练习题A  --  CodeForces - 1008C Reorder the Array You are given an array of inte ...

  6. 暑期集训2:ACM基础算法 例2:POJ-2456

    2018学校暑期集训第二天--ACM基础算法 例二  --   POJ - 2456 Aggressive cows Farmer John has built a new long barn, wi ...

  7. 暑期集训2:ACM基础算法 例1:POJ-1064

    2018学校暑期集训第二天--ACM基础算法 例一  --  POJ - 1064 Cable master Inhabitants of the Wonderland have decided to ...

  8. 第02期 基础算法(Leetcode)刻意练习开营计划

    背景 如果说 Java 是自动档轿车,C 就是手动档吉普.数据结构与算法呢?是变速箱的工作原理.你完全可以不知道变速箱怎样工作,就把自动档的车子从 A 开到 B,而且未必就比懂得的人慢.写程序这件事, ...

  9. 【基础算法】算法,从排序学起(一)

    本文目录 1.导言 2.谈谈排序 2.1 何为排序?(What is sorting?) 2.2 排序的应用(Why sorting?) 2.3 常见排序算法的种类(How to sort?) 3.基 ...

  10. 计算机及网络应用基础思维导图_计算机基础/算法/面试题 PDF+思维导图下载

    之前为了面试,整理了九大应付面试的思维导图 + 一份 630 页的程序员内功修炼手册 + 一份计算机基础/算法/Java技术栈/Linux C++技术栈的资料.当时我就是靠着这份思维导图以及整理的 P ...

最新文章

  1. 原创,真正解决iframe高度自适应的问题.兼容各浏览器
  2. 第一天2017/03/28
  3. 读《程序是怎样跑起来》第五章有感
  4. mysql编译方式安装_mysql编译方式安装
  5. ASP.NET实现推送文件到浏览器的方法
  6. SpringBoot编写sh脚本进行启停
  7. Ubuntu 出现apt-get: Package has no installation cand
  8. cocos2d-x3.10 适配 IPV6
  9. echo 多行_分享laravel-echo-server广播服务搭建-Laravel
  10. DropDownList 实现分页不包含选择值
  11. 基于netty实现socketio的聊天室
  12. shell如何清除linux系统所有任务,技术|RHCE 系列(四): 使用 Shell 脚本自动化 Linux 系统维护任务...
  13. SNMP弱口令导致的网络入侵
  14. android跳到自带浏览器打开pdf
  15. 格力如失去经销商支持,或将进一步落后于美的,董明珠慌了么?
  16. configure: error: Package requirements (sqlite3 」 3.7.4) were not met:
  17. SONET与SDH的关系
  18. debian VBoxManage 命令行安装 win2003
  19. js php mysql 是b,MySQL_BBS(php mysql)完整版(七),//下面是 top.js function KB_kee - phpStudy...
  20. 易语言程序加密的原则

热门文章

  1. 计算机应届博士生的一点求职经验——华为篇
  2. 2016012028 赵莉 散列函数的应用及其安全性
  3. 小白学Django第九天| Cookie和session的那些骚操作
  4. Django REST framework的使用简单介绍
  5. 华为2288H V5 重装系统无法开机问题
  6. Java黑皮书课后题第4章:*4.24(对三个城市排序)编写一个程序,提示用户输入三个城市名称,然后以升序进行显示
  7. 尚硅谷python培训多少钱
  8. linux 内核 风扇,Linux CPU温度,风扇监测lm-sensors
  9. Xilinx文档编号及其内容索引
  10. 【ThreeJS基础教程-初识Threejs】1.3 右手坐标系