[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 ...
随机推荐
- 【POJ】【2601】Simple calculations
推公式/二分法 好题! 题解:http://blog.csdn.net/zck921031/article/details/7690288 这题明显是一个方程组……可以推公式推出来…… 然而这太繁琐了 ...
- SQL Server优化
虽然查询速度慢的原因很多,但是如果通过一定的优化,也可以使查询问题得到一定程度的解决. 查询速度慢的原因很多,常见如下几种: 没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) I/ ...
- extjs4 与 kindeditor
<link rel="stylesheet" href="<?php echo Yii::app()->request->baseUrl;?> ...
- AD转换后数字量的处理
假设模拟输入电压的最大值为5V,A/D转换器件为8位转换. [该转换器的分辨率为1/2n=0.3906%.] [能分辨输入模拟电压变化的最小值为5*0.3906%=19.5mv.] 则模拟电压与数字输 ...
- hdu 1698 线段树 区间修改
#include <cstdio> #include <cstdlib> #include <cmath> #include <map> #includ ...
- 使用 Microsoft Word 发布博客文章
以 Microsoft Word 2010 为例: 依次选择:文件 -> 保存并发送 -> 发布为博客文章 配置说明:新建账户 的 博客文章 URL 一栏填写 http://rpc.cn ...
- 了解Javascript 变量
javascript语言变量的作用域可以分为局部变量和全局变量 函数内部定义的变量为局部变量,作用范围在整个函数体内,函数外定义的变量为全局变量,如果在函数内部定义变量时没有使用关键字var,那么该变 ...
- BZOJ1083: [SCOI2005]繁忙的都市
水题之王SP…这题就裸的最小生成树 /************************************************************** Problem: 1083 User ...
- Codeforces 475D CGCDSSQ(分治)
题意:给你一个序列a[i],对于每个询问xi,求出有多少个(l,r)对使得gcd(al,al+1...ar)=xi. 表面上是询问,其实只要处理出每个可能的gcd有多少个就好了,当左端点固定的时候,随 ...
- iOS工程预编译文件的创建
在搜索 添加工程名/自己的pch文件名记住加后缀