[珂泰]16-成長最長の部分数列
3345 ワード
最も長い部分数列(11053)
数列Aを与えた場合、最長増分部分数列を求める問題.
LISとも呼ばれます.
部分数列?数列を選択して作成した数列.
数列の数値の順序は変更できません.
連続性を扱うためには,最後の数が何であるかが重要である.
D[i][j]->iは長さであり、jは最後の数である.
既存の数を利用しているので,1次元解が可能である.
どんな方法で来るのかわからないわけではないので、jはいりません.
D[i] = A[1], ....A[i]に列挙する場合、最後のA[i]を増分した最長部分の列の長さ.
D[i]にはA[i]を含める必要があります.
一番長い部分の数列はA[?]で、A[?], ... ,A[j],A[i]で重なる部分を探してみます.
D[i]=A[1]~A[i],A[i]を最後のLISの長さとする.
問題の個数=N.
解答時間=N
O(N^2)
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n= sc.nextInt();
int a[]= new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
int d[]=new int[n];
for(int i=0;i<n;i++) {
d[i]=1;
for(int j=0;j<i;j++){
if(a[j] < a[i] && d[i] < d[j]+1) {
d[i] = d[j]+1;
}
}
}
int res =d[0];
for(int i=0;i<n;i++) {
res = Math.max(d[i], res);
}
System.out.println(res);
}
}
最も長い部分の列4
LISの長さを求めて、それからLISが何なことを出力します.
V[i]=A[i]の前の数値インデックス、すなわちA[i]の前のA[V[i]でなければ、長さが最も長い.
import java.util.*;
public class Main {
static int a[];
static int d[];
static int v[];
static void go(int p) {
if(p==-1) return;
go(v[p]);
System.out.println(a[p]+" ");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n= sc.nextInt();
a = new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
d=new int[n];
v=new int[n];
for(int i=0;i<n;i++) {
d[i]=1;
v[i]=-1;
for(int j=0;j<i;j++){
if(a[j] < a[i] && d[i] < d[j]+1) {
d[i] = d[j]+1;
v[i]=j;
}
}
}
int res =d[0];
int p=0;
for(int i=0;i<n;i++) {
if(res < d[i]) {
res = d[i];
p = i;
}
}
System.out.println(res);
go(p);
System.out.println();
}
}
連続(1912)
n個の整数からなる任意の数列を与える.
私たちはその中からいくつかの連続した数字を選んで、求められる和の中で最大の和を求めたいと思っています.
ただし、数値は1つ以上選択する必要があります.
この問題の入力は、負の値、正の値、またはゼロ度です.
最大の和を求めるには正数が必要です.しかし、負数計算も削除できません.
-1も含まれていますが、3、-1、3なら正解かもしれません.
D[i]=iが2番目の数字で終わる最大連続.
このように式を求めるには,iの第一手をできるだけ数える.
正解:D[1]、、、、、D[N]の最大値.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n= sc.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
int d[]=new int[n];
for(int i=0;i<n;i++) {
d[i] = a[i];
if(i==0) {
continue;
}
if(d[i] < d[i-1] + a[i]) {
d[i] = d[i-1] + a[i];
}
}
int res = d[0];
for(int i=0;i<n;i++) {
res = Math.max(res, d[i]);
}
System.out.println(res);
}
}
これは崔伯俊先生のコードテストの基礎科目に基づいて書いた文章です.Reference
この問題について([珂泰]16-成長最長の部分数列), 我々は、より多くの情報をここで見つけました https://velog.io/@tms01365/코테16-가장-긴-증가하는-부분-수열テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol