今天还是动态规划,我都快被动态规划搞心态了。
P1091 [NOIP2004 提高组] 合唱队形
题目描述
nn 位同学站成一排,音乐老师要请其中的 n-kn−k 位同学出列,使得剩下的 kk 位同学排成合唱队形。
合唱队形是指这样的一种队形:设 kk 位同学从左到右依次编号为 1,2,1,2, … ,k,k,他们的身高分别为 t_1,t_2,t1,t2, … ,t_k,tk,则他们的身高满足 t_1< \cdots <t_i>t_{i+1}>t1<⋯<ti>ti+1> … >t_k(1\le i\le k)>tk(1≤i≤k)。
你的任务是,已知所有 nn 位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
输入格式
共二行。
第一行是一个整数 nn(2\le n\le1002≤n≤100),表示同学的总数。
第二行有 nn 个整数,用空格分隔,第 ii 个整数 t_iti(130\le t_i\le230130≤ti≤230)是第 ii 位同学的身高(厘米)。
输出格式
一个整数,最少需要几位同学出列。
输入输出样例
输入 #1复制
8 186 186 150 200 160 130 197 220
输出 #1复制
4
说明/提示
对于 50\%50% 的数据,保证有 n \le 20n≤20。
对于全部的数据,保证有 n \le 100n≤100。
分析:
1,从右往左,按左高右低顺序找出每一个位置右边有几个从高到低的数,即为b[i](包括自己).
2,从左往右,按左低右高顺序找出每一个位置左边有几个从低到高的数,即为b[i](包括自己).
3,接着就可以把自己左边的从低到高的数和右边从高到低的数相加,记得减一。
代码如下:
#include<stdio.h>
#include<math.h>
#include<string.h>
int n,a[105],b[105],c[105],m;
int max(int x,int y)
{
return x>y?x:y;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
for(int i=1;i<=n;i++)
{
for(int j=0;j<i;j++)
{
if(a[i]>a[j])
b[i]=max(b[i],b[j]+1);
}
}
for(int i=n;i>0;i--)
{
for(int j=n+1;j>i;j--)
{
if(a[i]>a[j])
c[i]=max(c[i],c[j]+1);
}
}
for(int i=1;i<=n;i++)
{
m=max(b[i]+c[i]-1,m);
}
printf("%d",n-m);
}
P1439 【模板】最长公共子序列
题目描述
给出 1,2,\ldots,n1,2,…,n 的两个排列 P_1P1 和 P_2P2 ,求它们的最长公共子序列。
输入格式
第一行是一个数 nn。
接下来两行,每行为 nn 个数,为自然数 1,2,\ldots,n1,2,…,n 的一个排列。
输出格式
一个数,即最长公共子序列的长度。
输入输出样例
输入 #1复制
5 3 2 1 4 5 1 2 3 4 5
输出 #1复制
3
说明/提示
- 对于 50\%50% 的数据, n \le 10^3n≤103;
- 对于 100\%100% 的数据, n \le 10^5n≤105。
分析:
1,这个题目我之前做过一次,如果我没有记错的话,但是它的数据比我之前做过的那个题目要卡的严格一些。
2,用dp[i]记录以ii为长度的最长上升子序列的末尾元素的最小值,以l1记录目前的最长上升子序列,这样可以保证dp数组单调递增。
3,然后我们通过二分法找位置就行。
代码如下:
#include<stdio.h>
#include<math.h>
#include<string.h>
int n,n1,a[100005],b[100005],dp[100005];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&n1);
a[n1]=i;
}
for(int i=1;i<=n;i++)
{
scanf("%d",b+i);
b[i]=a[b[i]];
}
int l1,l,r,m;
l1=1;
dp[1]=b[1];
for(int i=2;i<=n;i++)
{
if(dp[l1]<b[i])
dp[++l1]=b[i];
else
{
l=1;r=l1;
while(l<r)
{
m=(l+r)/2;
if(dp[m]>b[i])
r=m;
else
l=m+1;
}
dp[l]=b[i];
}
}
printf("%d",l1);
}
总结:
动态规划不容易啊,是我一直以来的一个瓶颈,遇到难点的题目就写不出来了。