zoukankan      html  css  js  c++  java
  • LA 2678 Subsequence

    有一个正整数序列,求最短的子序列使得其和大于等于S,并输出最短的长度。

    用数组b[i]存放序列的前i项和,所以b[i]是递增的。

    遍历终点j,然后在区间[0, j)里二分查找满足b[j]-b[i]≥S的最大的i,时间复杂度为O(nlongn)。

    这里二分查找用到库函数lower_bound()

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 100000 + 10;
     9 int a[maxn], b[maxn];
    10 
    11 int main(void)
    12 {
    13     #ifdef LOCAL
    14         freopen("2678in.txt", "r", stdin);
    15     #endif
    16 
    17     int n, S;
    18     while(scanf("%d%d", &n, &S) == 2)
    19     {
    20         for(int i = 1; i <= n; ++i)
    21         {
    22             scanf("%d", &a[i]);
    23             b[i] = b[i-1] + a[i];
    24         }
    25         int ans = n + 1;
    26         for(int j = 1; j <= n; ++j)
    27         {
    28             int i = lower_bound(b, b+j, b[j]-S) - b;
    29             if(i > 0)
    30                 ans = min(ans, j-i+1);
    31         }
    32         printf("%d
    ", ans == n+1 ? 0 : ans);
    33     }
    34     return 0;
    35 }
    代码君一

    继续优化:

    由于j是递增的,bj也是递增的,所以bi-1≤bj-S的右边也是递增的。换句话说满足条件的i的位置也是递增的

    虽然有两层循环,但是i的值只增不减,所以时间复杂度为O(n)

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 100000 + 10;
     9 int a[maxn], b[maxn];
    10 
    11 int main(void)
    12 {
    13     #ifdef LOCAL
    14         freopen("2678in.txt", "r", stdin);
    15     #endif
    16 
    17     int n, S;
    18     while(scanf("%d%d", &n, &S) == 2)
    19     {
    20         for(int i = 1; i <= n; ++i)
    21         {
    22             scanf("%d", &a[i]);
    23             b[i] = b[i-1] + a[i];
    24         }
    25         int ans = n + 1;
    26         int i = 1;
    27         for(int j = 1; j <= n; ++j)
    28         {
    29             if(b[i-1] > b[j] - S)
    30                 continue;
    31             while(b[i] <= b[j] - S)
    32                 ++i;
    33             ans = min(ans, j-i+1);
    34         }
    35         printf("%d
    ", ans == n+1 ? 0 : ans);
    36     }
    37     return 0;
    38 }
    代码君二
  • 相关阅读:
    msado15.tlh中重要的枚举(精简)
    VC连接SQL2005(例子ADO_2)
    [转]VC++创建一个线程并传递参数
    vc实现文件的打印--BOOL Print_html(const char *sURL)
    求一个整数n对16求商和余数
    vc下文件的创建--使用fstream和CFile
    vc连接Access2003
    Goldengate Parameter SUPPRESSTRIGGERS & DEFERREFCONST
    DEFERRED_SEGMENT_CREATION
    Duplicate standby database from active database
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3887561.html
Copyright © 2011-2022 走看看