poj 3298 Antimonotonicity DP

来源:互联网 发布:java中的init方法 编辑:程序博客网 时间:2024/05/01 01:25
 

小菜菜说下这道题,因为15分钟搞定的,而且一次A了。

题意就是求最长的符合那个条件的序列,当然,不一定连续。

 

首先,如果没有任何符合条件的情况出现,那么最长的就是每个元素本身,长度为1。

 

思路:先说个概念,大元素:大于前面的,大于后面的。

从2出发,1是大元素。如果大元素遇见比它本身大的,则最大解不变,遇见的这个元素仍为大元素,如果遇见比它小的元素,则最大解+1,遇见的这个元素成小元素,下一个就考虑遇见的这个元素;

同样,如果是小元素遇见比它小的,则最优解长度不变,遇见的这个元素仍为小元素,如果是遇见比它大的,则最优解+1,遇见的这个元素为大元素,下一个就考虑遇见的这个元素;

 

我弄了这么个, int dp[30005][4];  dp[i][0]==1代表当前的第i个元素是作为大元素在序列中的(<i >),dp[i][0]==0代表当前的第i个元素是作为小元素在序列中的(>i <);dp[i][1]就是考虑前i个元素的的最大解。

 如果有幸被牛人看见的话请不吝指教哈~

 

代码挺菜的。

#include "stdio.h"#include "iostream"using namespace std;int main(){    int m,n,i,j,w,t;    int a[30005];    int dp[30005][4];    while(scanf("%d",&t)!=EOF)    {        while(t--)        {            scanf("%d",&n);            for(i=1; i<=n; i++)                scanf("%d",&a[i]), dp[i][1]=1, dp[i][2]=a[i];            dp[1][0] = 1;            if(a[1] > a[2])            {                  dp[2][1]=2, dp[2][2]=a[2];            }            for(i=2; i<=n; i++)            {                if(dp[i-1][0])                {                    if(a[i] < dp[i-1][2])                    {                        dp[i][0]=0;  dp[i][1]=dp[i-1][1]+1;                    }                    else                    {                        dp[i][0]=dp[i-1][0];  dp[i][1]=dp[i-1][1];                    }                    dp[i][2]=a[i];                }                else                {                    if(a[i] > dp[i-1][2])                    {                        dp[i][0]=1;  dp[i][1]=dp[i-1][1]+1;                    }                    else                    {                        dp[i][0]=dp[i-1][0];  dp[i][1]=dp[i-1][1];                    }                    dp[i][2]=a[i];                }            }            printf("%d\n",dp[n][1]);        }//t--    }    return 0;}//752K 172MS


 

752K  172MS

 

原创粉丝点击