2678 - Subsequence
A sequence of N positive integers(10 <N < 100 000), each of them less than or equal 10000, and a positive integerS(S
< 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal toS.
Input
Many test cases will be given. For each test case the program has to read the numbersN andS, separated by an interval, from the first line. The numbers of
the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.
Output
For each the case the program has to print the result on separate line of the output file. If there isn't such a subsequence, print 0 on a line by itself.
Sample Input
10 15 5 1 3 5 10 7 4 9 2 8 5 11 1 2 3 4 5
Sample Output
2 3
解題思路:該題目,解法不唯一,我這裡有兩種。一種方法是用隊列,儲存現在所運用的數列中的資料,當資料有變時,對和進行判斷,要是sum>=s,就處理以前入隊的資料,要是可以刪,就刪除(彈出),記錄滿足要求的隊列的最小大小(長度),最後輸出結果即可(要是結果為變數初值,要輸出”0“).第二種方法是,用動態規劃的思想,用數組儲存數列中包括該值的前面的值的和,只要sum[i]-sum[j]>=s(i>j),則連續i-j的值的和就是滿足sum[]>=s的。
隊列解法:
#include<stdio.h>#include<queue>using namespace std;int main(){ int n,min1,s,x,y; int sum; while(scanf("%d%d",&n,&s)!=EOF) { queue<int> q; sum=0; min1=0xfffffff; for(int i=0;i<n;i++) { scanf("%d",&x); sum+=x; q.push(x); //入隊 y=q.front(); while(sum-y>=s) //將距離縮到最短 { sum-=y; q.pop(); y=q.front(); } if(sum>=s&&q.size()<min1) //找最短距離 min1=q.size(); } if(min1==0xfffffff) //若計數變數為初值,直接值0輸出 min1=0; printf("%d\n",min1); } return 0;}
動態規劃思想解法:
#include<stdio.h>int main(){ int n,s; int x,min1; int i,j; int sum[100000]; while(scanf("%d%d",&n,&s)!=EOF) { min1=0xfffffff; j=0; for(i=1;i<=n;i++) { scanf("%d",&x); sum[i]=sum[i-1]+x; while(sum[i]-sum[j]>=s) j++; if(sum[i]-sum[j-1]>=s) { j--; if(i-j<min1) min1=i-j; } } if(min1==0xfffffff) min1=0; printf("%d\n",min1); } return 0;}