poj 1836 最長上公升 下降子串行

2021-08-03 11:25:15 字數 1466 閱讀 8741

alignment

題意:輸入一串數字代表著一列排好隊的軍人的身高,現在要求從其中移走一些人,使得剩餘在隊伍中的任何乙個人都可以向左或者向右看到隊伍的頭。隊伍中身高並列最高的幾個人不會相互阻礙,但是其餘的身高相同的人會相互阻礙視線,求最少要移出多少人才能滿足要求。

首先理解一下題意,拋開背景,題目要求在一列數中移出最少的數,使得從左到右先是遞增,到乙個頂點後一直遞減。最大的頂點可以連續有幾個相同大小的,其餘的數必嚴格遞增或者遞減。這樣,我們可以把題目轉化為最長上公升/下降子串行來處理,將上公升和下降的過程分兩次來做。組合後找出最長的先上公升後下降的序列,答案就是用原隊伍人數減去最長先上公升後下降子串行長度。(需要考慮只遞增無遞減或者只遞減無遞增的情況)

先來求最長上公升序列。a[i]表示第i個數的大小。用b[i]表示第i個數作為最大值時,最長上公升序列數量是多少。則b[i+1]值為1~j(1<=j<=i)數里小於a[i+1]且b[i]值最大的數加一。表示為 b[i] = max(b[1~j])+1,(ja[j])。**如下:

b[1]=1;

for(int i=2;i<=n;i++)

}b[i]=max;

}

求最長下降子串行的方法類似,只是求解過程相反,從右向左求最長上公升子串行。c[i]表示以第i個數表示最大值時,最長下降子串行的數量。**如下:

c[n]=1;

for(int i=n-1;i>=1;i--)

}c[i]=max;

}

現在我們已知了以各點作為頂點的最長上公升/下降子串行。以i表示上公升序列中最高的點,j表示下降序列中最高的點,由於可以最高點可以有數個相同大小的,所以i和j可能不相同。迴圈判斷各種和j組合i的情況,找出最大值。**如下:

int num=0;

int max=0;

for(int i=1;i<=n;i++)

if(num>max)

}} }

下面是我ac的完整**:

#include#includeusing namespace std;

int n;

float a[1010],b[1010],c[1010];

int dp[1010][1010];

int main()

b[1]=1;

for(int i=2;i<=n;i++)

}b[i]=max; }

c[n]=1;

for(int i=n-1;i>=1;i--)

}c[i]=max;

} int num=0;

int max=0;

for(int i=1;i<=n;i++)

if(num>max)

}} }

cout << n-max << endl;

return 0;

}

POJ 1836(動規,上公升下降子串行問題)

poj 1836,動規問題,上公升下降子串行問題,和普通的上公升 下降子串行問題最大的不同 要考慮佇列中點乙個或兩個的情況 include using namespace std intmain left i 以i位元素結尾的最長上公升子串行 for int i 0 i for int j 0 j ...

Dp 最長上公升子串 最長上公升子串行

乙個數的子串bi,當b1 b2 bs的時候,我們稱這個子串是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串 ai1,ai2,aik 這裡1 i1 i2 ik n。如 對於序列 1,7,3,5,9,4,8 有它的一些上公升子串,如 1,7 3,5,9 等等。這些子串中最長...

poj2533 最長上公升子串

題目大意 給你乙個字串,你要從裡邊找到最長的子串的長度,且這個子串必須是公升序。解題思路 dp 狀態變數 d i 以i結尾的最長上公升子串的長度 狀態轉移方程 d i max d i d j 1 j邊界 全初始化為1,因為每乙個單獨的字元都是乙個子串 include include include ...