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 ...