[HDU] 4512 吉哥系列故事——完美队形I(有点dp味道的递归模拟)
题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=4512
方法:F(a,b)为在a,b段间能获得找出的最多人数,则原问题的解为:
F(1,n)=Max({F'(i,n)| 1=<i<=n })
对于每一个F'(i,n),计算过程如下:
首先计算出在i到n段,等于第i个数的最后的值的位置j,根据i和j的关系,若i==j 直接返回1,如i==j-1,返回2,其他情况, 在i+1 和 j-1这段中,枚举每一个大于第i个数的数的位置p,递归去计算每一个F'(p,j-1),取出最大的一个加上2得到一个F'(i,n);而递归计算每一个F'(p,j-1)的方法和计算每一个F'(i,n)一样。
代码:
#include <iostream>
#include <queue>
#include <map>
#include<algorithm>
using namespace std;
int nums[201];
int dp[202][202];
int n;
int found(int x,int st,int ed=n)
{
if(dp[st][ed]!=-1)
return dp[st][ed];
if(st==ed)
return 1;
int newEnd;
for(int i=ed;i>=st;i--)
{
if(nums[st]==nums[i])
{
newEnd=i;
break;
}
}
int px = (newEnd==st ? 1:2);
int max=0;
for(int i=st+1;i<=newEnd-1;i++)
{
if(nums[i]>nums[st])
{
int re = found(0,i,newEnd-1);
max = max>re ? max:re;
}
}
return dp[st][ed]=px+max;
}
int main()
{
int tc = 0;
scanf("%d",&tc);
while(tc>0)
{
memset(dp,-1,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&nums[i]);
int sum=0,end=n,max=0;
for(int i=1;i<=n;i++)
{
int re = found(i,i,n);
max =max > re ? max:re;
}
cout<<max<<endl;
tc--;
}
return 0;
}
感想:不要看漏条件,题目要求左到中是递增的,否则结果会是超时再WA,
浙公网安备 33010602011771号