码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3670 Eating Together (①O(n)的dp,②最长字段和)

时间:2015-04-15 19:37:54      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:poj   3670   c   

题目大意:找到队列中不符合非升(降)序趋势的编号个数,

分别判断升序跟降序的个数,最后取最小。

两种方法:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

#define maxn 30005

int n;
int cow[maxn];
int f[maxn][5];

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &cow[i]);
    memset(f, 0, sizeof(f));
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            f[i][j] = f[i - 1][1];
            for (int k = 2; k <= j; k++)
                f[i][j] = min(f[i][j], f[i - 1][k]);
            if (cow[i] != j)
                f[i][j]++;
        }
    }

    int ans = n;
    for (int i = 1; i <= 3; i++)
        ans = min(ans, f[n][i]);

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            f[i][j] = f[i - 1][3];
            for (int k = 2; k >= j; k--)
                f[i][j] = min(f[i][j], f[i - 1][k]);
            if (cow[i] != j)
                f[i][j]++;
        }
    }
    for (int i = 1; i <= 3; i++)
        ans = min(ans, f[n][i]);
    printf("%d\n", ans);

    return 0;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int sup=30005;
int LDS[sup];//不升
int LIS[sup];//不降
int dp[sup];
int n;
int bsearch(int beg,int end,int p)
{
    int mid;
    while(beg<=end)
    {
        mid=(beg&end)+((beg^end)>>1);
        if(dp[mid]<=p)
            beg=mid+1;
        else if(dp[mid]>p)
            end=mid-1;
    }
    return beg;
}
int lis()
{
    int i;
    int top=-1;
    for(i=0;i<n;++i)
    {
        if(dp[top==-1?0:top]<=LIS[i])
            dp[++top]=LIS[i];
        else if(dp[top==-1?0:top]>LIS[i])
            dp[bsearch(0,top,LIS[i])]=LIS[i];
    }
    return n-top-1;
}
int lds()
{
    int i,top=-1;
    for(i=0;i<n;++i)
    {
        if(dp[top==-1?0:top]<=LDS[i])
            dp[++top]=LDS[i];
        else if(dp[top==-1?0:top]>LDS[i])
            dp[bsearch(0,top,LDS[i])]=LDS[i];
    }
    return n-top-1;
}
int main()
{
    int i;
    scanf("%d",&n);
    for(i=0;i<n;++i)
    {
        scanf("%d",&LIS[i]);
        LDS[n-i-1]=LIS[i];
    }
    int ans=lis();
    fill(dp,dp+sup,0);
    int t=lds();
    ans=ans<t?ans:t;
    if(ans!=-1)
    printf("%d\n",ans);
    else
        printf("0\n");
    return 0;
}

POJ 3670 Eating Together (①O(n)的dp,②最长字段和)

标签:poj   3670   c   

原文地址:http://blog.csdn.net/wangxinxin_/article/details/45063241

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!