zoukankan      html  css  js  c++  java
  • [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,

  • 相关阅读:
    多页面通信问题
    Web Worker
    http 状态码(转载)
    如何把一个Array 复制到ArrayList中?
    使用C#数据如何导到excel
    面试题:Web Service与wcf的区别
    ASP.NET为我们提供了几种错误处理机制?
    使用sql语句创建带有输出参数的存储过程
    存储过程维护
    Linux系统下的网络配置
  • 原文地址:https://www.cnblogs.com/kbyd/p/3229532.html
Copyright © 2011-2022 走看看