您的位置:首页 > 其它

hdu 1423+hdu 4512 最长公共递增子序列

2015-12-19 13:12 417 查看
hdu1423 是 最长公共递增子序列的一个基本题 hdu 4512 是一个变式

基本算法就是 结合最长公共子序列和最长递增子序列 的算法。

附: 最长递增子序列:/article/8874641.html 最长公共子序列+变式:/article/8874656.html

结合以下代码应该能明白 最长公共递增子序列 的算法。

然后说 hdu 4512 。我们把一个数组当作两个来看。比较慢的算法是,枚举排队在中间的人,左边作为一个数组右边作为一个数组。这样效率较低。

我们采取的方法是,枚举右边数组的最后一个数的位置,从左往右。具体看代码注释

#include<cstdio>//*****hdu 1423******  <span style="font-family: Arial, Helvetica, sans-serif;">*****hdu 1423******   </span><span style="font-family: Arial, Helvetica, sans-serif;">*****hdu 1423******</span>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<queue>
#define MS(x,y) memset(x,y,sizeof(x))
#define pi acos(-1.0)
using namespace std;
void fre(){freopen("t.txt","r",stdin);}
typedef long long LL;
typedef unsigned long long ULL;
const int MOD = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int MAXN = 4*(1e5)+1;
const int eps = -(1<<30);

int main()
{
// fre();
int t,n,m,dp[505];
int i,j,a[505],b[505];
scanf("%d",&t);
while(t--)
{
MS(dp,0);
scanf("%d",&n);//read
for(i = 1; i <= n; ++i) scanf("%d",&a[i]);
scanf("%d",&m);
for(i = 1; i <= m; ++i) scanf("%d",&b[i]);
for(i = 1; i <= n; ++i)//solve
{
int len = 0;
for(j = 1; j <= m; ++j)
{
if(a[i] > b[j])len = max(len,dp[j]);
else if(a[i] == b[j]) dp[j] = max(dp[j],len+1);
}
}
int ans = -1;
for(i = 1; i <= m; ++i) if(ans < dp[i]) ans = dp[i];//search
printf("%d\n",ans);
if(t!=0) printf("\n");
}
return 0;
}


#include<cstdio>//********hdu 4512**********
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<queue>
#define MS(x,y) memset(x,y,sizeof(x))
#define pi acos(-1.0)
using namespace std;
void fre(){freopen("t.txt","r",stdin);}
typedef long long LL;
typedef unsigned long long ULL;
const int MOD = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int MAXN = 4*(1e5)+1;
const int eps = -(1<<30);

int main()
{
//  fre();
int t,n,m,dp[205],loc[205];//loc表示左边某个士兵队友身高相等的右边士兵的位置
int i,j,a[205];
scanf("%d",&t);
while(t--)
{
MS(dp,0);
scanf("%d",&n);
for(i = 1; i <= n; ++i) scanf("%d",&a[i]);//read

for(i = n; i >= 1; --i) //solve  ,枚举右边序列的最后一个数的位置,对于i=k,i<k时计算的情况都仍然可用(想想为什么),因此直接计算。
{
int len = 0;
for(j = 1; j < i; ++j)//遍历左边序列
{
if(a[i] > a[j]) len = max(len,dp[j]);
else if(a[i] == a[j])
{
if(len+1>dp[j])//此处必须用>,用>= 是错误的,因为身高相等的不一定只有两个,我们必须选择距离远的两个人
{
loc[j] = i;
dp[j] = len+1;
}
}
}
}

int maxx = 1;
for(i = 1; i <= n; ++i)//search
{
if(dp[i]*2 >= maxx)//pay attention to "*2",此处必须用 >=。
{
maxx = dp[i]*2;
for(j = i; j < loc[i]; ++j)
{
if(a[j]>a[i])
{
maxx++;
break;
}
}
}
}
printf("%d\n",maxx);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: