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后面,然后 ...
随机推荐
- Python学习进程(3)Python基本数据类型
本节介绍在Python语法中不同的变量数据类型. (1)基本数据类型: >>> a=10; >>> b=10.0; >>> c=T ...
- linux基础三---网络基础&软件包管理
一 ifconfig:显示所有正在启动的网卡的详细信息或设定系统中网卡的IP地址. ifconfig eno16777736 down/up 关闭/开启 eno16777736 网卡 ifconf ...
- Python绿色版
Python 安装的时候,有个选项,是问你要安装给所有用户还是只安装给当前用户,你只要选择当前用户,就会把那些需要的 dll ,包括 msvcr90.dll 都给装到 Python 目录下,你只要把 ...
- git上面创建个人简历-链接
github创建个人在线简历: https://segmentfault.com/a/1190000006820290
- 适配iOS9问题汇总
iOS 9适配过程中出现的问题,收集的链接资料供大家学习分享. http://wiki.mob.com/ios9-对sharesdk的影响(适配ios-9必读)/ http://www.cocoach ...
- nohup后台运行jar与关闭
nohup 用途:LINUX命令用法,不挂断地运行命令. 语法:nohup Command [ Arg ... ] [ & ] 描述:nohup 命令运行由 Command 参数和任何相关 ...
- python进阶02
1.import导入模块 import sys sys.path:显示的是:从显示目录中查找要导入的模块文件. 程序执行时导入模块路径:sys.path.append('/home/itcast/xx ...
- myEclipse 2014 破解教程
因为经常在不同电脑里安装配置下载myEclipse,所以干脆记录下来,一直找度娘也是很麻烦的. 此教程仅对myEclipse2014 有效. 破解工具:https://pan.baidu.com/s/ ...
- kafka原理学习好文
摘自:http://blog.csdn.net/suifeng3051/article/details/48053965 http://blog.csdn.net/ychenfeng/article/ ...
- Java之File文件类
package IoDemo; import java.io.File; import java.io.FileFilter; import java.io.IOException; import j ...