算法介绍
- 算法简介:尺取法,又名two pointers(双指针法),是一种简洁而有效的dp优化算法,常见于将时间复杂度O($n^2$)的一般dp优化为O(n)。
- 适用条件:限制变量随着指针的单向移动,而呈单调变化。
- 实现细节:
- 申请两个指针$p_1$,$p_2$。
- 固定$p_1$,使$p_2$递增直至满足条件。
- 保持$p_2$不动,使$p_1$向右移动,回到2。
模板分析
Sum
- 题意:输入一个含有n个元素的单调不降数列。输出所有数对$a_i,a_j(1 \le i < j \le n)$,使得$a_i+a_j=m$。
- O($n^2$)朴素算法:枚举i和j,使得$a_i+a_j=m$。
- O(n)时间优化:对于任意数对$a_i,a_j$,限制变量sum满足i或j向右移动时,sum单调不降。(尺取法适用条件) 因此i向右移动时,要使sum不变,j应向左移动,可用尺取法优化。
#include<cstdio>
using namespace std;
const int MAXN=100010;
int n,m;
int a[MAXN];
inline void read()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
}
int main()
{
read();
for(int i=1,j=n;i<=n;i++)//初始化j在最右,保证获取到第一个解
{
while(j-1>i&&a[i]+a[j-1]>=m)j--;//i增大时j减小,预判是否满足条件
if(i<j&&a[i]+a[j]==m)//确认条件以防越界
printf("%d %d\n",a[i],a[j]);
}
return 0;
}
原文地址:https://www.cnblogs.com/-SingerCoder/p/12422387.html
时间: 2024-11-10 04:37:06