ACM学习历程—SNNUOJ1213 加油站问题(动态规划 || 数学)
题目链接:http://219.244.176.199/JudgeOnline/problem.php?id=1213
这是这次微软实习面试的一道题,当时只相出了一个2n的做法,面试官让我优化成n的做法。不过当时没想出来,最后面试官提示到了最后才恍然大悟。
题目大意就是在一个环上有n个加油站,已知第i个加油站可以提供ai的油量,从第i个加油站到第i+1个加油站需要消耗bi的油量。(当i为n时,则表示n到1的油量)
问:是否能从某个加油站出发,绕环一圈回到这个加油站?(当途中到达某个加油站时的油量小于0则不可)。
首先可以设f(i) = a(i)-b(i),然后就可以转换成,在某个点出发回到这个点的过程中f的sum值恒大于等于0。然后就联系到最大子序列和,如果从最大子序列的起点处出发都不能绕一圈,那么显然任何位置都不行,因为任何位置出发经过最大子序列时,必然sum值小于最大子序列和,这样的话后面必然某处会出现小于0的情况。不然的话,这个位置就能构成更大的子序列,就矛盾了。
于是,我需要计算出环上的最大子序列,我想到的方法便是倍长一下,然后再求,于是就变成了2n的做法。代码中可以稍微优化一下就不需要f数组了。
关于O(n)的做法,其实也挺好想的,不过当时面试的时候,一紧张就思维混乱了。
首先如果从某个i出发,到j的时候sum(i, j)小于0了。那么[i ,j]间所有的点k出发到j处的sum(k, j)都会小于0,因为i能到k,自然sum(i, k)大于等于0,而sum(i, j) = sum(i, k-1)+sum(k, j),必然sum(k, j)要更小一点。那么[i, j]间的点都可以排除了。于是可以直接从0点出发绕一圈,遇到i不行,就继续从i+1出发,直到能跑完或者跑到n的位置处。
代码(n的做法):
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>
#define LL long long using namespace std; const int maxN = ;
int n, a[maxN], b[maxN]; void input()
{
for (int i = ; i < n; ++i) scanf("%d", &a[i]);
for (int i = ; i < n; ++i) scanf("%d", &b[i]);
} void work()
{
int rest;
bool flag;
for (int i = ; i < n; ++i)
{
flag = true;
rest = ;
int j;
for (j = ; j < n; ++j)
{
if (rest < )
{
flag = false;
break;
}
rest += a[(i+j)%n]-b[(i+j)%n];
}
if (flag && rest >= )
{
printf("Yes\n");
return;
}
else i = min(i+j, n);
}
printf("No\n");
} int main()
{
//freopen("test2.in", "r", stdin);
//freopen("test2.out", "w", stdout);
while (scanf("%d", &n) != EOF)
{
input();
work();
}
return ;
}
代码(2n的做法):
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>
#define LL long long using namespace std; const int maxN = ;
int n, a[maxN], b[maxN]; void input()
{
for (int i = ; i < n; ++i) scanf("%d", &a[i]);
for (int i = ; i < n; ++i) scanf("%d", &b[i]);
} void work()
{
int maxFrom, maxSum = ;
int from = , sum = , len = *n-;
for (int i = ; i < len; ++i)
{
if (sum >= )
{
sum += a[i%n]-b[i%n];
if (sum > maxSum)
{
maxSum = sum;
maxFrom = from;
}
}
else
{
sum = a[i%n]-b[i%n];
from = i%n;
}
}
sum = ;
for (int i = ; i < n; ++i)
{
if (sum < )
{
printf("No\n");
return;
}
sum += a[(maxFrom+i)%n]-b[(maxFrom+i)%n];
}
if (sum >= ) printf("Yes\n");
else printf("No\n");
} int main()
{
//freopen("test.in", "r", stdin);
//freopen("test2.out", "w", stdout);
while (scanf("%d", &n) != EOF)
{
input();
work();
}
return ;
}
ACM学习历程—SNNUOJ1213 加油站问题(动态规划 || 数学)的更多相关文章
- ACM学习历程—HDU 5512 Pagodas(数学)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5512 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是给了初始的集合{a, b},然后取集合里 ...
- ACM学习历程—HDU5586 Sum(动态规划)(BestCoder Round #64 (div.2) 1002)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5586 题目大意就是把一段序列里面的数替换成f(x),然后让总和最大. 首先可以计算出初始的总和,以及每 ...
- ACM学习历程—HDU 5073 Galaxy(数学)
Description Good news for us: to release the financial pressure, the government started selling gala ...
- ACM学习历程—FZU2191完美的数字(数学)
Description Bob是个很喜欢数字的孩子,现在他正在研究一个与数字相关的题目,我们知道一个数字的完美度是 把这个数字分解成三个整数相乘A*A*B(0<A<=B)的方法数,例如数字 ...
- ACM学习历程——POJ1260 Pearls(动态规划)
Description In Pearlania everybody is fond of pearls. One company, called The Royal Pearl, produces ...
- ACM学习历程—HDU2476 String painter(动态规划)
http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意是给定一个起始串和一个目标串,然后每次可以将某一段区间染成一种字符,问从起始串到目标串最少需要染多 ...
- ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)
http://acm.hdu.edu.cn/showproblem.php?pid=5696 这是这次百度之星初赛2B的第一题,但是由于正好打省赛,于是便错过了.加上2A的时候差了一题,当时有思路,但 ...
- ACM学习历程—Hihocoder 1290 Demo Day(动态规划)
http://hihocoder.com/problemset/problem/1290 这题是这次微软笔试的第三题,过的人比第一题少一点,这题一眼看过去就是动态规划,不过转移方程貌似不是很简单,调试 ...
- ACM学习历程—HDU5587 Array(数学 && 二分 && 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5587 题目大意就是初始有一个1,然后每次操作都是先在序列后面添加一个0,然后把原序列添加到0后面,然后 ...
随机推荐
- Loadrunder脚本篇——Running Time setting之Additional attributes
作用说明 为Vuser脚本提供额外自定义参数.额外参数设置可应用于所有Vuser脚本类型. 说明: Add:添加一个参数 Remove:移除一个参数 可以在这里先输入一些常用的参数名及对应的值,类似常 ...
- Loadrunder之脚本篇——参数化方法
导语 参数化旨在模拟多数据来进行测试,所以再选择参数化你明确你参数化的内容! 方法一 1.确定需要参数化的内容 2.选中需要参数化的内容 3.右键选中的内容->Replace with a Pa ...
- Raspberry Pi开发之旅-同步时间
使用htpdate同步时间 由于树莓派板子上没有 RTC 硬件和电池,因此树莓派上的系统时间重启是保存不了的.网上已经有人想到应对 NTP 被防火墙封掉类似的需求了,开源的 htpdate 命令直接使 ...
- Windos Server 2008 FTP 服务安装
安装服务:FTP 系统环境:Windos 2008 R2 x64 安装FTP服务 管理-->角色-->添加角色-->Web 服务器 IIS 测试
- 线性代数:Ax=b的解
n列的矩阵A,当且仅当向量b是列空间C(A)的一个向量时,Ax=b有解. C(A)的零空间是N(A),N(A)正交补是A的行空间C(T(A)), 依据上一章的结论,任何Rn向量可以表示为r+n,其中n ...
- Kubernetes client-go
Github地址:https://github.com/kubernetes/client-go 访问kubernetes集群有几下几种方式: 方式 特点 支持者 Kubernetes dashboa ...
- maven setting.xml 存放位置导致deply失败,显示没有权限401错误
settings.xml存在于两个地方: 1.安装的地方:$M2_HOME/conf/settings.xml 2.用户的目录:${user.home}/.m2/settings.xml 我只在mav ...
- H3C光模块相关命令和检测方法
<Sysname> dis transceiver interface GigabitEthernet 1/0/28 查看 GigabitEthernet1/0/28 transcei ...
- springcloud-声明式调用服务Feign
springcloud项目例子:链接:https://pan.baidu.com/s/1O1PKrdvrq5c8sQUb7dQ5Pg 密码:ynir 作用: 基于Netflix Feign整合了Rib ...
- hive学习8(小案例1练习)
创建数据库 hive> create database feigu; hive> use feigu; 创建表 stg_job表 drop table if exists stg_job; ...