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


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

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

    两种方法:

    #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
    ", 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
    ",ans);
        else
            printf("0
    ");
        return 0;
    }
    

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    清除ListBox的列表项(删除所有项目)
    创建对象
    搜索功能
    为下拉式菜单(DropDownList)添加第一个选项
    事件接口
    用户控件(UserControl) 使用事件 Ver2
    MS SQL动态创建临时表
    炒粉还是煮面
    输入数字动态创建行
    DataList中TextBox onfocus调用后台静态方法
  • 原文地址:https://www.cnblogs.com/wanglaoda/p/4937146.html
Copyright © 2020-2023  润新知