题目:https://www.vijos.org/p/1303
思路:
第一问最长不上升子序列,第二问运用定理:
一个序列中,最长不上升子序列的最小覆盖度等于序列中最长上升自序列的长度。
(由于求的额外的,所以再减一)
注意:LIS用的时候注意n=1的情况,别瞎输出。还有dp数组初始化全了,别漏下。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a[25],dp[25];
int main() {
int n=0,cnt1=0,cnt2=0;
char c;
while(scanf("%d%c",&a[n++],&c)==2)
if(c=='\n')
break;
for(int i=1;i<n;i++){
dp[i]=1;dp[0]=1; //初始化插在循环里固然好,但别漏下。
for(int j=0;j<i;j++)
if(a[i]<=a[j])
dp[i]=max(dp[j]+1,dp[i]);
cnt1=max(dp[i],cnt1);
}
memset(dp,0,sizeof(dp));
//不上升子序列覆盖度等于最长上升子序列
for(int i=1;i<n;i++){
dp[i]=1;dp[0]=1;
for(int j=0;j<i;j++)
if(a[i]>a[j])
dp[i]=max(dp[j]+1,dp[i]);
cnt2=max(dp[i],cnt2);
}
cnt2--;
if(n==1){
cout<<1<<","<<0<<endl;
return 0;
}
cout<<cnt1<<","<<cnt2<<endl;
return 0;
}