D - Subsequence
POJ - 3061 <----------- 原题在这
题目大意
给定数组a,求其符合∑a[i] > S 的最短子数列。
尺取法解析
蒟蒻这道题WA了8次qwq
形同上图:
- 首先取两边界L,R。
- 若∑(L→R)a[i] < S,则右边界R++。
- 直到∑(L→R)a[i] > S,更新其最小值,左边界L++。
- 当右移左边界满足∑(L→R)a[i] < S时,返回第二步右移右边界。
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int BOKI = 1e5+10;
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int T; cin >> T;
while(T--){
int n,S,a[BOKI],b[BOKI];
memset(b,0,sizeof(b));
cin >> n >> S;
for(int i = 0;i < n;i++){
cin >> a[i];
b[i+1] = b[i]+a[i]; //这里是计算前缀和awa
}
if(b[n]<S){
cout << "0" << endl; continue;
}
int i = 0,j = 1,minn = n; //i为左边界,j为右边界
while(true){
while(b[j]-b[i]<S&&j<=n) j++;
if(b[j]-b[i] < S) break;
minn = min(minn,j-i);
i++;
}
cout << minn << endl;
}
return 0;
}