我的解决方案 - SPOJ - ALTSEQ 有什么问题
What is wrong with my solution - SPOJ - ALTSEQ?
我需要做什么:我需要在SPOJ上解决[这个]问题。
给定一个由 N 个整数 a1、a2、a3、...aN 我必须找到数组最长交替子序列的长度。
交替序列 b1, b2 ...bk, k>=1 是一个序列,具有以下 2 个属性:
- |b1|<|b2|<|b3|<.....<|bk|
- 符号在相邻元素之间交替,即,如果 b1> 0,则 b2<0、b3>0 等。或者,如果为 b1<0,则为 b2>0、b3<0 等。
我的方法:
该问题是最长递增子序列 (LIS) 问题的变体。这是我基于记忆的递归解决方案:
#include <cstdio>
using namespace std;
long *a;
int *dp;
int solve(int);
int main()
{
int n;
scanf("%d", &n);
a = new long[n];
dp = new int[n]{};
for (int i = 0; i < n; i++) scanf("%ld", a+i);
printf("%d", solve(n-1));
}
int solve(int n)
{
if (dp[n]) return dp[n];
int &m = dp[n] = 1, k;
for(int j = 0; j < n; j++)
if (((a[n] < 0 && a[j] > 0 && -a[n] > a[j]) || (a[n] > 0 && a[j] < 0 && a[n] > -a[j])))
if ((k = 1 + solve(j)) > m) m = k;
return m;
}
我的问题:这个解决方案在裁判系统上给出了错误的答案,所以它一定有问题。我需要帮助来找出此解决方案的问题所在,因为我无法独自一人。
后来我突然想到,solve(i) 正在计算 dp[i],即以第 i 个元素结尾的 LIS。因此,整个 dp 数组的最大值是正确答案,而不是我之前打印的 dp[n-1]。
此外,递归解决方案可以转换为自下而上以提高效率。此外,在自下而上的情况下,所涉及的两个环路中的外侧一个可以与输入读取环路相结合,并且可以在外环路本身内跟踪最大dp[i],以避免再次通过找到最大值。这应该会带来更快的解决方案。
#include <cstdio>
using namespace std;
int main()
{
int n, k, m = 0;
scanf("%d", &n);
long *a = new long[n];
int *dp = new int[n];
for (int i = 0; i < n; i++) {
scanf("%ld", a+i);
dp[i] = 1;
for (int j = 0; j < i; j++)
if (((a[i] < 0 && a[j] > 0 && -a[i] > a[j]) || (a[i] > 0 && a[j] < 0 && a[i] > -a[j])) && (k = 1 + dp[j]) > dp[i]) dp[i] = k;
if (dp[i] > m) m = dp[i];
}
printf("%dn", m);
}
相关文章:
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 格式说明符C++有什么问题
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 我的堆栈和库存清单程序的结构有什么问题?
- 此工厂功能有什么问题?
- 以下 C++ 代码有什么问题?
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了