• [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,

  • 相关阅读:
    Angular2.0的学习(四)
    JAVA 中BIO,NIO,AIO的理解
    分布式调用技术 RPC VS REST
    深入浅出单实例Singleton设计模式
    接口设计六大原则
    线程安全的简单理解
    class<T>和 class<?>类型 有什么区别
    随笔记录
    问题记录总结
    JDK1.8 新特性(全)
  • 原文地址:https://www.cnblogs.com/kbyd/p/3229532.html
Copyright © 2020-2023  润新知