zoukankan      html  css  js  c++  java
  • 尺取法 POJ 3601 Subsequence

    题目传送门

     1 /*
     2     题意:求连续子序列的和不小于s的长度的最小值
     3     尺取法:对数组保存一组下标(起点,终点),使用两端点得到答案
     4         1. 记录前i项的总和,求[i, p)长度的最小值,用二分找到sum[p] - s[i] >= s的p
     5         2. 除了O (nlogn)的方法,还可以在O (n)实现,[i, j)的区间求和,移动两端点,更新最小值,真的像尺取虫在爬:)
     6 */
     7 #include <cstdio>
     8 #include <algorithm>
     9 #include <cstring>
    10 #include <cmath>
    11 using namespace std;
    12 
    13 typedef long long ll;
    14 const int MAXN = 1e5 + 10;
    15 const int INF = 0x3f3f3f3f;
    16 int a[MAXN];
    17 ll sum[MAXN];
    18 
    19 int main(void)        //POJ 3601 Subsequence
    20 {
    21     int t;    scanf ("%d", &t);
    22     while (t--)
    23     {
    24         memset (sum, 0, sizeof (sum));
    25         int n, s;
    26         scanf ("%d%d", &n, &s);
    27         for (int i=1; i<=n; ++i)    {scanf ("%d", &a[i]);    sum[i] = sum[i-1] + a[i];}
    28 
    29         if (sum[n] < s)    {puts ("0");    continue;}
    30 
    31         int ans = n;
    32         for (int i=1; sum[i]+s<=sum[n]; ++i)
    33         {
    34             int p = lower_bound (sum+i, sum+1+n, sum[i] + s) - sum;
    35             ans = min (ans, p - i);
    36         }
    37 
    38         printf ("%d
    ", ans);
    39     }
    40 
    41     return 0;
    42 }
    43 
    44 
    45 /*
    46 2
    47 10 15
    48 5 1 3 5 10 7 4 9 2 8
    49 5 11
    50 1 2 3 4 5
    51 */
     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cmath>
     5 using namespace std;
     6 
     7 typedef long long ll;
     8 const int MAXN = 1e5 + 10;
     9 const int INF = 0x3f3f3f3f;
    10 int a[MAXN];
    11 
    12 int main(void)        //POJ 3601 Subsequence
    13 {
    14     int t;    scanf ("%d", &t);
    15     while (t--)
    16     {
    17         int n, s;
    18         scanf ("%d%d", &n, &s);
    19         for (int i=1; i<=n; ++i)    scanf ("%d", &a[i]);
    20 
    21         int ans = n + 1;    int i = 1, j = 1;    ll sum = 0;
    22         while (1)
    23         {
    24             while (j <= n && sum < s)    sum += a[j++];
    25             if (sum < s)    break;
    26             ans = min (ans, j - i);
    27             sum -= a[i++];
    28         }
    29 
    30         if (ans == n + 1)    puts ("0");
    31         else    printf ("%d
    ", ans);
    32     }
    33 
    34     return 0;
    35 }
    36 
    37 
    38 /*
    39 2
    40 10 15
    41 5 1 3 5 10 7 4 9 2 8
    42 5 11
    43 1 2 3 4 5
    44 */
    O (n)
    编译人生,运行世界!
  • 相关阅读:
    水波模拟算法
    火车调度问题
    讨论范式
    字符串编码传输
    意识的物质,物质的意识
    需求分析——项目日志管理系统
    委托揭秘
    [9]OCP:开放封闭原则
    NULL OBJECT 模式
    由《通用权限设计》而引发的随想
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4550206.html
Copyright © 2011-2022 走看看