两个数组,一个表示第i位有之前递增最大子序列是几个,另一个表示第i位之后递减最大子序列是几个。
两个数组是独立的,所以最后在遍历每一个下标的时候,让两个数组相加(因为两个数组都包含了第i位的数,所以要-1)
#include
using namespace std ;
const int N = 1010;
int a[N] , f1[N],f2[N];
int main()
{
int n ;
cin >> n ;
for(int i = 1; i <= n;i++)
{
cin >> a[i];
f1[i] = 1 ;
f2[i] = 1 ;
}
for(int i = 2; i <= n ; i++)
{
for(int j = 1 ; j < i ; j++)
{
if(a[j] < a[i])
{
f1[i] = max(f1[i],f1[j]+1);
}
}
}
for(int i = n - 1; i ; i--)
{
for(int j = n ; j > i; j--)
{
if(a[j] < a[i])
{
f2[i] = max(f2[i],f2[j]+1);
}
}
}
int ans = 0;
for(int i = 1 ; i <= n ; i++ )
{
ans = max(ans, f1[i] + f2[i] -1);
}
cout << ans;
return 0 ;
}
#include
using namespace std ;
const int N = 1010;
int a[N] , f1[N],f2[N];
int main()
{
int n ;
cin >> n ;
for(int i = 1; i <= n;i++)
{
cin >> a[i];
f1[i] = 1 ;
f2[i] = 1 ;
}
for(int i = 2; i <= n ; i++)
{
for(int j = 1 ; j < i ; j++)
{
if(a[j] < a[i])
{
f1[i] = max(f1[i],f1[j]+1);
}
}
}
for(int i = n - 1; i ; i--)
{
for(int j = n ; j > i; j--)
{
if(a[j] < a[i])
{
f2[i] = max(f2[i],f2[j]+1);
}
}
}
int ans = 0;
for(int i = 1 ; i <= n ; i++ )
{
ans = max(ans, f1[i] + f2[i] -1);
}
cout << n - ans;
return 0 ;
}
点击跳转至题目
思路:
合法的桥一一对应上升子序列
#include
#include
using namespace std;
typedef pair<int,int> PII ;
const int N = 5010;
PII a[N];
int f[N];
int main()
{
int n ;
cin >>n;
for(int i = 1 ; i<= n;i++)
{
int x,y;
cin >> x >> y;
a[i].first = x , a[i].second = y ;
f[i] = 1;
}
sort(a+1,a+n+1);
int res = 0;
for(int i = 1; i <= n ; i++)
{
for(int j = 1 ; j < i ; j++)
{
if(a[i].second > a[j].second)
{
f[i] = max(f[i] , f[j]+1);
}
}
res = max(res,f[i]);
}
cout << res;
return 0 ;
}
点击跳转至题目
思路:
f【】数组从当前位置最多个数变成最大总和
#include
using namespace std;
const int N = 1010;
int f[N], a[N];
int main()
{
int n;
cin >> n;
for(int i = 0 ; i < n ; i++)
{
cin >> a[i];
f[i] = a[i] ;
}
int res = 0;
for(int i = 0 ; i < n ; i++)
{
for(int j = 0; j < i ; j++)
{
if(a[j] < a[i])
{
f[i] = max(f[i] ,f[j] + a[i]);
}
}
res = max(res,f[i]);
}
cout << res ;
return 0;
}