uva 10534 (dp专组H题)
2016-05-02 19:36
330 查看
题意:给一个长度为n的数字序列A,找到一个长度为2*k+1的子序列,使得前k+1个数单调上升,后k+1个数单调递减。输出2*k+1。
题解:
用cnt1[i]记录给定数组A到第i个元素,最长上升子序列的长度。求最长上升子序列的长度链接:http://blog.csdn.net/sinat_30062549/article/details/47193899
翻转数组A得到数组B
用cnt2[i]记录给定数组B到第i个元素,最长上升子序列的长度。
则,cnt[n-1-i]表示数组A中从i到n-1最长下降子序列的长度。
min(cnt1[i],cnt2[n-1-i])表示以第i个元素为中心的(k+1)的大小。
遍历i(0<=i<n)得到最大的k+1,记为ans。
输出2*ans-1为答案。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10005;
int a[maxn];
int b[maxn];
int dp[maxn];
int cnt1[maxn];
int cnt2[maxn];
int n;
int lis(int *a){
int len = 1;dp[1] = a[0];
cnt1[0] = 1;
for(int i = 1;i<n;i++){
int t = a[i];
if(t>dp[len]){dp[++len] = a[i];cnt1[i] = len;}
else{
int p = lower_bound(dp+1,dp+len+1,t)-dp;
dp[p] = t;
cnt1[i] = p;
}
}
return len;
}
int main(){
while(cin>>n){
for(int i = 0;i<n;i++){
cin>>a[i];
b[n-1-i] = a[i];
}
int len1 = lis(a);
for(int i = 0;i<n;i++){
cnt2[i] = cnt1[i];
}
int len2 = lis(b);
/* for(int i = n-1;i>=0;i--)
cout<<cnt1[i]<<" ";
cout<<endl;
for(int i = 0;i<n;i++)
cout<<cnt2[i]<<" ";
cout<<endl;*/
int ans = 0;
for(int i = 0;i<n;i++){
int mi = min(cnt2[i],cnt1[n-1-i]);
ans = max(mi,ans);
}
cout<<ans*2-1<<endl;
}
}
题解:
用cnt1[i]记录给定数组A到第i个元素,最长上升子序列的长度。求最长上升子序列的长度链接:http://blog.csdn.net/sinat_30062549/article/details/47193899
翻转数组A得到数组B
用cnt2[i]记录给定数组B到第i个元素,最长上升子序列的长度。
则,cnt[n-1-i]表示数组A中从i到n-1最长下降子序列的长度。
min(cnt1[i],cnt2[n-1-i])表示以第i个元素为中心的(k+1)的大小。
遍历i(0<=i<n)得到最大的k+1,记为ans。
输出2*ans-1为答案。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10005;
int a[maxn];
int b[maxn];
int dp[maxn];
int cnt1[maxn];
int cnt2[maxn];
int n;
int lis(int *a){
int len = 1;dp[1] = a[0];
cnt1[0] = 1;
for(int i = 1;i<n;i++){
int t = a[i];
if(t>dp[len]){dp[++len] = a[i];cnt1[i] = len;}
else{
int p = lower_bound(dp+1,dp+len+1,t)-dp;
dp[p] = t;
cnt1[i] = p;
}
}
return len;
}
int main(){
while(cin>>n){
for(int i = 0;i<n;i++){
cin>>a[i];
b[n-1-i] = a[i];
}
int len1 = lis(a);
for(int i = 0;i<n;i++){
cnt2[i] = cnt1[i];
}
int len2 = lis(b);
/* for(int i = n-1;i>=0;i--)
cout<<cnt1[i]<<" ";
cout<<endl;
for(int i = 0;i<n;i++)
cout<<cnt2[i]<<" ";
cout<<endl;*/
int ans = 0;
for(int i = 0;i<n;i++){
int mi = min(cnt2[i],cnt1[n-1-i]);
ans = max(mi,ans);
}
cout<<ans*2-1<<endl;
}
}
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- 1.10055 - Hashmat the brave warrior
- 2.10071 - Back to High School Physics
- 3.458 - The Decoder
- 4.694 - The Collatz Sequence
- 6.494 - Kindergarten Counting Game
- 7.490 - Rotating Sentences
- 8.414 - Machined Surfaces
- 9.488 - Triangle Wave
- A.457 - Linear Cellular Automata
- B.489 - Hangman Judge
- C.445 - Marvelous Mazes
- 1.10494 - If We Were a Child Again