PAT甲级 Perfect Sequence (25) 记忆化搜索

题目分析:

意思是要求对于一个给出的数组,我们在其中尽可能多选数字,使得所选数字的max <= min * p,而由于数据量较大直接二层循环不加优化实现是不现实的,由题意得知,对于数字序列的子序列选择没有连续性要求,就是可以随便选的意思,所以我们先将整个序列从小到大排序(这样在遍历时j-i+1就是你选择的个数),从第i == 1个元素开始往后搜索,只要能满足max <= min * p就继续搜索,直到不满足的退出,而在i+1个元素开始搜索时我们发现,由于下标为i+1的元素一定比i大(从小到大排序),所以之前i元素能达到的最远max,i+1元素是必然能达到的,所以i+1元素开始的位置就是i元素的最右极限+1(我用cnt记录i元素本次搜索能达到的最远的下标,i+1从cnt+1开始搜索)

本题代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int N = 100005;
 7 int k[N];
 8 int n, p, ans;
 9 
10 int main(){
11     scanf("%d%d", &n, &p);
12     for(int i = 1; i <= n; i++) scanf("%d", &k[i]);
13     sort(k+1, k+n+1); 
14     ans = 0;
15     int cnt = 0;
16     for(int i = 1; i <= n; i++){
17         if(n - i + 1 > ans){
18             for(int j = cnt+1; j <= n; j++){
19                 if(k[j] <= p * k[i]){
20                     cnt++;
21                     j-i+1 > ans ? ans = j-i+1 : ans;
22                 }else break;
23             }
24         }else break;
25     }
26     printf("%d
", ans);
27     return 0;
28 } 
原文地址:https://www.cnblogs.com/YLTFY1998/p/12303607.html