poj3061 Subsequence
//O(nlogn) #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX_N = 1e5; int n, S; int a[MAX_N], sum[MAX_N + 1]; void solve() { memset(sum, 0, sizeof(sum)); // 计算 sum for (int i = 0; i < n; i++) sum[i + 1] = sum[i] + a[i]; if (sum[n] < S) { cout << 0 << endl; return; } int res = n; for (int s = 0; sum[s] + S <= sum[n]; s++) { // 利用二分搜索法求出t int t = lower_bound(sum + s, sum + n, sum[s] + S) - sum - s; res = min(res, t); } cout << res << endl; } int main() { int t; cin >> t; while (t--) { cin >> n >> S; for (int i = 0; i < n; i++) cin >> a[i]; solve(); } return 0; }
//优化:O(n) #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAX_N = 1e5; int n, S; int a[MAX_N], sum[MAX_N + 1]; void solve() { int res = n + 1; int s = 0, t = 0, sum = 0; // 初始化 for (; ; ) { while (t < n && sum < S) // 只要 t没有超出范围, 且sum没达到S,就不断将sum增加a[t],并且将t增加1 { sum += a[t++]; } if (sum < S) break; // 若所有数加起来,仍小于S,则此后不可能再有res的更新,可以退出循环,否则更新res res = min(res, t - s); sum -= a[s++]; // 将sum减去as,s增加1后,回到s不断增加at,t++的循环 } if (res > n) res = 0; cout << res << endl; } int main() { int t; cin >> t; while (t--) { cin >> n >> S; for (int i = 0; i < n; i++) cin >> a[i]; solve(); } return 0; }