题目连接:
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,