吉哥系列故事——完美隊形I
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1367 Accepted Submission(s): 385
Problem Description
吉哥這幾天對隊形比較感興趣。
有一天,有n個人按順序站在他的面前,他們的身高分別是h[1], h[2] ... h[n],吉哥希望從中挑出一些人,讓這些人形成一個新的隊形,新的隊形若滿足以下三點要求,則稱之為完美隊形:
1、挑出的人保持他們在原隊形的相對順序不變;
2、左右對稱,假設有m個人形成新的隊形,則第1個人和第m個人身高相同,第2個人和第m-1個人身高相同,依此類推,當然,如果m是奇數,中間那個人可以任意;
3、從左到中間那個人,身高需保證遞增,如果用H表示新隊形的高度,則H[1] < H[2] < H[3] .... < H[mid]。
現在吉哥想知道:最多能選出多少人組成完美隊形?
Input
第一行輸入T,表示總共有T組數據(T <= 20);
每組數據先輸入原先隊形的人數n(1<=n <= 200),接下來一行輸入n個整數,表示按順序從左到右原先隊形位置站的人的身高(50 <= h <= 250,不排除特別矮小和高大的)。
Output
請輸出能組成完美隊形的最多人數,每組數據輸出占一行。
Sample Input
2
3
51 52 51
4
51 52 52 51
Sample Output
3
4
Source
2013騰訊編程馬拉松初賽第二場(3月22日)
Recommend
liuyiding
思路 :
把輸入序列倒置 求2者最長公共上升子序列
?#include<stdio.h>
#include<string.h>
int a[222],b[222],dp[222];
int get(int n,int m)
{
int i,j;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
int pos=0;
for(j=1;j<=n-i+1;j++)
{
if(b[j]<a[i]&&dp[j]+1>dp[pos]) pos=j;
if(b[j]==a[i])
{
if(j!=(n-i+1))//不是自己和自己匹配了
{
if(dp[j]<(dp[pos]+2))
dp[j]=dp[pos]+2;
}
else//自己和自己匹配了
{
if(dp[j]<(dp[pos]+1))
dp[j]=dp[pos]+1;
}
//if(dp[j]<dp[pos]+1)
// dp[j]=dp[pos]+1;
}
}
}
int ans=0;
for(i=0;i<222;i++)
if(dp[i]>ans) ans=dp[i];
return ans;
}
int main()
{
int cas,i,j,n;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
j=1;
for(i=n;i>=1;i--)
b[i]=a[j++];
int ans=get(n,n);
printf("%d\n",ans);
}
return 0;
}
#include<stdio.h>
#include<string.h>
int a[222],b[222],dp[222];
int get(int n,int m)
{
int i,j;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
int pos=0;
for(j=1;j<=n-i+1;j++)
{
if(b[j]<a[i]&&dp[j]+1>dp[pos]) pos=j;
if(b[j]==a[i])
{
if(j!=(n-i+1))//不是自己和自己匹配了
{
if(dp[j]<(dp[pos]+2))
dp[j]=dp[pos]+2;
}
else//自己和自己匹配了
{
if(dp[j]<(dp[pos]+1))
dp[j]=dp[pos]+1;
}
//if(dp[j]<dp[pos]+1)
// dp[j]=dp[pos]+1;
}
}
}
int ans=0;
for(i=0;i<222;i++)
if(dp[i]>ans) ans=dp[i];
return ans;
}
int main()
{
int cas,i,j,n;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
j=1;
for(i=n;i>=1;i--)
b[i]=a[j++];
int ans=get(n,n);
printf("%d\n",ans);
}
return 0;
}
上面是從1開始輸入的 下面是蔥0開始輸入的 不知道為什麼總是錯
求大神指導下
?#include<stdio.h>
#include<string.h>
int a[222],b[222],dp[222];
int get(int n,int m)
{
int i,j;
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
int pos=0;
for(j=0;j<=n-i-1;j++)
{
if(b[j]<a[i]&&dp[j]+1>dp[pos]) pos=j;
if(b[j]==a[i])
{
if(j!=(n-i-1))//不是自己和自己匹配了
{
if(dp[j]<(dp[pos]+2))
dp[j]=dp[pos]+2;
}
else//自己和自己匹配了
{
if(dp[j]<(dp[pos]+1))
dp[j]=dp[pos]+1;
}
//if(dp[j]<dp[pos]+1)
// dp[j]=dp[pos]+1;
}
}
}
int ans=0;
for(i=0;i<222;i++)
if(dp[i]>ans) ans=dp[i];
return ans;
}
int main()
{
int cas,i,j,n;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
j=0;
for(i=n-1;i>=0;i--)
b[i]=a[j++];
int ans=get(n,n);
printf("%d\n",ans);
}
return 0;
}
#include<stdio.h>
#include<string.h>
int a[222],b[222],dp[222];
int get(int n,int m)
{
int i,j;
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
int pos=0;
for(j=0;j<=n-i-1;j++)
{
if(b[j]<a[i]&&dp[j]+1>dp[pos]) pos=j;
if(b[j]==a[i])
{
if(j!=(n-i-1))//不是自己和自己匹配了
{
if(dp[j]<(dp[pos]+2))
dp[j]=dp[pos]+2;
}
else//自己和自己匹配了
{
if(dp[j]<(dp[pos]+1))
dp[j]=dp[pos]+1;
}
//if(dp[j]<dp[pos]+1)
// dp[j]=dp[pos]+1;
}
}
}
int ans=0;
for(i=0;i<222;i++)
if(dp[i]>ans) ans=dp[i];
return ans;
}
int main()
{
int cas,i,j,n;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
j=0;
for(i=n-1;i>=0;i--)
b[i]=a[j++];
int ans=get(n,n);
printf("%d\n",ans);
}
return 0;
}