对于数字N,我们将 LIS数组定义为
以该数字结尾的数字的最长严格增加的子序列。
例如,假设4位数字是1531,那么 LIS数组将是[1,2,2,1]。
在第一个数字结束的最长增长子序列是1(数字1本身),第二个数字是2([1,5]),第三个数字也是2([1,3]),第四个数字是1(数字1本身)。
这里我使用的是bitmasking算法
for(int i=2;i<=n;i++){
int x = Lis[i];
if(x==1){
for(int j=1;j<(1<<10);j++){
int last=-1;
int len=0;
for(int k=9;k>=0;k--)
if((j&(1<<k))!=0){
len++;
if(len==1)
last=k;
}
for(int k=0;k<=last;k++){
dp[1<<k][i] = (dp[1<<k][i]+ dp[j][i-1])%mod;
}
}
continue;
}
for(int j=1;j<(1<<10);j++){
int last=-1;
int len=0;
for(int k=9;k>=0;k--)
if((j&(1<<k))!=0){
len++;
if(len==1)
last=k;
}
if(len+1!=x) continue;
for(int k=last+1;k<10;k++)
dp[j|(1<<k)][i] = (dp[j|(1<<k)][i]+ dp[j][i-1])%mod;
}
}
但它无法正常工作?任何人都可以解释我处理这个问题的正确方法吗?
答案 0 :(得分:0)
对于每个数字存储,最长相关序列的长度并按顺序进行:
max_len[]
result
for digit in sequence
max_len[digit] = max(sub_array(max_len, 1, digit - 1)) + 1
result.append(max_len[digit])
因为max_len
的长度为9或10,具体取决于输入序列中是否允许0,此解决方案在O(n)
中运行。 result
包含LIS数组。
基本思想是将输入序列中元素e
的LIS递归地定义为e
之前且小于e
的任何元素的LIS。由于我们想要最长的序列,我们显然选择具有最长序列的前任。我们可以将此值记忆为以元素e
结尾供以后使用的最长序列,并将e
的LIS长度添加到输出序列。