[POJ3061]Subsequence(二分,前缀和)
题目链接:http://poj.org/problem?id=3061
题意:给一个长为n的数列和整数s,求一个连续的子序列,使得这个子序列长度最短并且不小于这个整数s。
统计[1~i]的子序列和sum(i),(sum(0)=0)。然后求一个区间[i,j]的和即为sum(j)-sum(i-1) (i > 0)。
由于给定序列没有负数,因此sum是个严格不减的序列。
转换成一个求最大值最小的问题,可以二分枚举序列长度,在前缀和上计算子序列[i-1,i+m-1]的和。如果存在一个满足子序列和≥s的,则缩小序列长度并记下当前值,反之扩大。复杂度为O(nlgn)。
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath> using namespace std; const int maxn = ;
int n, s;
int x[maxn];
int sum[maxn]; bool ok(int mm) {
for(int i = ; i <= n - mm + ; i++) {
// printf("%d %d\n", i-1, i+mm-1);
if(sum[i+mm-] - sum[i-] >= s) return ;
}
return ;
} int main() {
// freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T--) {
memset(sum, , sizeof(sum));
scanf("%d %d", &n, &s);
for(int i = ; i <= n; i++) {
scanf("%d", &x[i]);
sum[i] = sum[i-] + x[i];
}
if(sum[n] < s) {
printf("0\n");
continue;
}
int ans;
int ll = ;
int rr = n;
while(ll <= rr) {
int mm = (ll + rr) >> ;
if(ok(mm)) {
ans = mm;
rr = mm - ;
}
else ll = mm + ;
}
printf("%d\n", ans);
}
}
此题也可以用尺取法,维护两个指针从左到右扫描所存序列,复杂度为O(n)。
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath> using namespace std; const int maxn = ;
int n, s;
int x[maxn]; int main() {
// freopen("in", "r", stdin);
int T;
scanf("%d", &T);
while(T--) {
scanf("%d %d", &n, &s);
int sum = ;
for(int i = ; i <= n; i++) {
scanf("%d", &x[i]);
sum += x[i];
}
if(sum < s) {
printf("0\n");
continue;
}
int ans = 0x7f7f7f;
int ll = ;
int rr = ;
sum = ;
while() {
while(rr <= n && sum <= s) {
sum += x[rr++];
}
if(sum < s) break;
ans = min(ans, rr-ll);
sum -= x[ll++];
}
printf("%d\n", ans);
}
}
[POJ3061]Subsequence(二分,前缀和)的更多相关文章
- Poj 3061 Subsequence(二分+前缀和)
Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12333 Accepted: 5178 Descript ...
- POJ3061 Subsequence(二进制前缀和法律+仿真足)
二分法+前缀和法律 满足子序列长度的条件(0,n)之间,sum[x+i]-sum[i]从i元素开始序列长度x和.前缀和可在O(n)的时间内统计 sum[i]的值.再用二分找出满足条件的最小的子序列长度 ...
- POJ-3061 Subsequence 二分或尺取
题面 题意:给你一个长度为n(n<100000)的数组,让你找到一个最短的连续子序列,使得子序列的和>=m (m<1e9) 题解: 1 显然我们我们可以二分答案,然后利用前缀和判断 ...
- poj 3061 Subsequence 二分 前缀和 双指针
地址 http://poj.org/problem?id=3061 解法1 使用双指针 由于序列是连续正数 使用l r 表示选择的子序列的起始 每当和小于要求的时候 我们向右侧扩展 增大序列和 每当和 ...
- POJ 3061 (二分+前缀和or尺取法)
题目链接: http://poj.org/problem?id=3061 题目大意:找到最短的序列长度,使得序列元素和大于S. 解题思路: 两种思路. 一种是二分+前缀和.复杂度O(nlogn).有点 ...
- Codeforces Round #381 (Div. 2) D. Alyona and a tree 树上二分+前缀和思想
题目链接: http://codeforces.com/contest/740/problem/D D. Alyona and a tree time limit per test2 secondsm ...
- POJ3061 Subsequence 尺取or二分
Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...
- 题解报告:poj 3061 Subsequence(前缀+二分or尺取法)
Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...
- 【BZOJ-1926】粟粟的书架 二分 + 前缀和 + 主席树
1926: [Sdoi2010]粟粟的书架 Time Limit: 30 Sec Memory Limit: 552 MBSubmit: 616 Solved: 238[Submit][Statu ...
随机推荐
- 【BZOJ】【1485】【HNOI2009】有趣的数列
Catalan数/组合数取模 Aha!这题我突然灵光一现就想到Catalan数……就是按顺序安排1~2n这些数(以满足前两个条件)……分配到奇数位置上的必须比偶数位置上的多(要不就不满足第三个条件了) ...
- lle算法
http://www.pami.sjtu.edu.cn/people/xzj/introducelle.htm
- UML基本表示法(转载)
UML是流行的图解符号.我们都知道,UML是可视化,说明,构建和记录软件和非软件系统的组成部分.这里的可视化是最重要的部分,需要被理解和记忆. UML符号是最重要的建模元素.适当有效地使用符号是非常重 ...
- 理解Linux系统负荷[转]
一.查看系统负荷 在Linux系统中,我们一般使用uptime命令查看(w命令和top命令也行).(另外,它们在苹果公司的Mac电脑上也适用.) 二.一个类比 我们不妨把这个CPU想象成一座大桥, ...
- MySQL复制中slave延迟监控
在MySQL复制环境中,我们通常只根据 Seconds_Behind_Master 的值来判断SLAVE的延迟.这么做大部分情况下尚可接受,但并不够准确,而应该考虑更多因素. 首先,我们先看下SLAV ...
- ***mysql中查询今天、昨天、上个月sql语句
今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天Select * FROM 表名 Where TO_DAYS( NOW( ) ...
- 由枚举模块到ring0内存结构 (分析NtQueryVirtualMemory)
是由获得进程模块而引发的一系列的问题,首先,在ring3层下枚举进程模块有ToolHelp,Psapi,还可以通过在ntdll中获得ZwQuerySystemInformation的函数地址来枚举,其 ...
- 【poj3358】消因子+BSGS 或 消因子+欧拉定理 两种方法
题意:给你一个分数,求它在二进制下的循环节的长度,还有第一个循环节从哪一位开始. For example, x = 1/10 = 0.0001100110011(00110011)w and 0001 ...
- hdu2021(很闲~~)
http://acm.hdu.edu.cn/showproblem.php?pid=2021 water~~~ #include<iostream> #include<stdio.h ...
- 李洪强漫谈iOS开发[C语言-041]-计算月份天数
李洪强漫谈iOS开发[C语言-041]-计算月份天数