[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 ...
随机推荐
- git shell 中文
alias ls="ls --show-control-chars" alias ll="ls -l"
- svg琐碎01
svg中的<g>主要用来做分组的定位,使用transform="translate(xOffset,yOffset)" 更改起始坐标. transform中的坐标是相对 ...
- BZOJ1083: [SCOI2005]繁忙的都市
水题之王SP…这题就裸的最小生成树 /************************************************************** Problem: 1083 User ...
- Google Chrome 浏览器禁用缓存
在使用 Google Chrome 浏览器调试 js 时,会发现修改完 js 不会立即生效,这是由于 chrome 浏览器缓存的原因,而在火狐下没有这个问题.经常使用 chrome 浏览器调试 js ...
- IDT hook KiTrap03
关于idt的基本知识就不进行赘述了,先看一个例子 0 ;------->进入内核,找到中断处理例程KiTrap03 0 这段代码执行,触发3号中断,然后开始执行KiTrap03例程,要知道,执行 ...
- JS之类型转换
一.显示类型转换 1.Boolean() (1).undefined/null/‘’ ==> false (2).任何对象(包括例如var obj = {} ) ==> true ( ...
- 【uva753/poj1087/hdu1526-A Plug for UNIX】最大流
题意:给定n个插座,m个插头,k个转换器(x,y),转换器可以让插头x转成插头y.问最少有多少个插头被剩下. 题解: 最大流或者二分图匹配.然而我不知道怎么打二分图匹配..打了最大流.这题字符串比较坑 ...
- lintcode:最小编辑距离
最小编辑距离 给出两个单词word1和word2,计算出将word1 转换为word2的最少操作次数. 你总共三种操作方法: 插入一个字符 删除一个字符 替换一个字符 样例 给出 work1=&quo ...
- hdu 4764 Stone (巴什博弈,披着狼皮的羊,小样,以为换了身皮就不认识啦)
今天(2013/9/28)长春站,最后一场网络赛! 3~5分钟后有队伍率先发现伪装了的签到题(博弈) 思路: 与取石头的巴什博弈对比 题目要求第一个人取数字在[1,k]间的某数x,后手取x加[1,k] ...
- python_ftplib实现通过FTP下载文件
1. Ftplib常用函数介绍 Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件,本次主要介绍连接FTP并且进行文件下载功能,可 ...