子序列问题

最长子序列

  1. 求最长子序列,满足和是一个数的倍数。
    题目链接
#include<bits/stdc++.h>
#define ll long long 
#define N 100005
int inf = 0x3f3f3f3f;
using namespace std;
ll n, k, a[N];
int main (){ 
    cin >> n >> k;  //N个数,所求序列和是K的倍数 

    for(int i = 1; i <= n; i++){    //读入数据 
        cin >> a[i];
    }

    int ans = 0;    //答案 
    for(int i = 1; i <= n; i++){
        if(n - i + 1 < ans)     //简单的n方复杂度不行,在这里加个判断
            break;              //如果后面的序列长度小于ans,就直接退出。 
        ll sum = 0;
        for(int j = i; j <= n; j++){    
            sum += a[j];    
            if(sum % k == 0){
                ans = max(ans, j - i + 1);
            }
        }
    }
    cout << ans <<endl;
    return 0;  
}  

最短子序列

  1. 求大与等于m的最短连续子序列
给出n个数,然后给一个数m,找出长度最短的连续子系列,其总和大于等于m。
n和m为正整数且n小于100 000,m小于100 000 000
若干组测试样例,处理到文件结束,注意无解情况输出0
第一行输入m,m。接下来一行有n个数。
input
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5
output
2
3

尺取法

#include<bits/stdc++.h>
#define ll long long 
#define N 100005
int inf = 0x3f3f3f3f;
using namespace std;
ll n, m, a[N], sum[N]; 
int main (){
    while(cin >> n >> m){
        a[0] = sum[0] = 0;
        for(int i = 1; i <= n; i++){
            cin >> a[i];
            sum[i] =sum[i-1] + a[i];    //读入并计算sum[i] sum为递增序列
        }
        int ans = n + 1;
        for(int i = 1; i <= n; i++){
            int t = lower_bound(sum + 1 + i, sum + 1 + n, m + sum[i - 1]) - sum;
            if(t <= n)
                ans = min(ans, t - i + 1);
        }   
        if (ans == n + 1)   //无解 
            ans = 0; 
        cout << ans <<endl; 
    }   
    return 0;  
}  
#include<bits/stdc++.h>
#define ll long long 
#define N 100005
int inf = 0x3f3f3f3f;
using namespace std;
ll n, m, a[N], sum[N]; 
int main (){
    while(cin >> n >> m){
        a[0] = sum[0] = 0;
        for(int i = 1; i <= n; i++){
            cin >> a[i];
            sum[i] =sum[i-1] + a[i];    //读入并计算sum[i] 
        }
        int ans = n + 1;
        int s = 0, e = 1;
        while(sum[e] - sum[s] < m){
            e ++;
        }
        while(e <= n){
//          while(sum[e] - sum[s] < m && e <= n) {  //要加上 e <= n,费则会 runtime error 
//              e ++;
//          }
            while(sum[e] - sum[s] >= m){    //更新最小序列 
                s ++;
            }
            ans = min(ans, e - s + 1);
            e ++;   //枚举下一个数 
            s ++;
        }
        if (ans == n + 1)   //无解
            ans = 0;  
        cout << ans <<endl; 
    }   
    return 0;  
}  
#include<bits/stdc++.h>
#define ll long long 
#define N 100005
int inf = 0x3f3f3f3f;
using namespace std;
ll n, m, a[N], sum[N]; 
int main (){
    while(cin >> n >> m){
        for(int i = 1; i <= n; i++){
            cin >> a[i];
        }
        int ans = n + 1;
        int s = 1, e = 1;
        ll sum = 0;
        while(1){
            while(sum < m && e <= n){
                sum += a[e++];
            }
            if(sum < m)
                break;
            ans = min(ans, e - s);
            sum -= a[s++];
        }

        if (ans == n + 1)   //无解
            ans = 0;  
        cout << ans <<endl; 
    }   
    return 0;  
}  
阅读更多

没有更多推荐了,返回首页