zoukankan      html  css  js  c++  java
  • POJ 3670 Eating Together

    POJ_3670

        由于递增和递减是类似的,下面不妨只讨论变成递增序列的情况。

        由于Di只有三个数,所以可以考虑将序列分割成三部分,第一部分全部变成1,第二部分全部变成2,第三部分全部变成3。然后我们枚举3开始的位置,这时一共有若干决策,要么前面的全部是1,要么前面有一段2,然后再前面有一段1或者没有,如果每种决策都考察一遍的话整体复杂度就要O(N^2)了,因此考虑优化一下。记当前的位置为i,1的最后一个位置为j,not1[k]表示k以及k之前不是1的数量,not2[k]表示k以及k之前不是2的数量,not3[k]表示k以及k之后不是3的数量,那么我们把决策表示成not2[i]+(not1[j]-not2[j])+not3[i+1],这样如果我们保留着前面所有j中not1[j]-not2[j]的最小值的话,就可以O(1)找到最优决策了。

        这个题目还有一个很好的思路就是直接求最长不降子序列,然后用N减去这个值,不过这样最好也只是O(NlogN)的复杂度。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXD 30010
    #define INF 0x3f3f3f3f
    int N, not3[MAXD], a[MAXD];
    void init()
    {
        int i;
        for(i = 1; i <= N; i ++) scanf("%d", &a[i]);
    }
    int deal()
    {
        int i, not1, not2, ans, opt;
        not3[N + 1] = 0;
        for(i = N; i >= 1; i --) not3[i] = not3[i + 1] + (a[i] != 3);
        ans = not3[1], not1 = not2 = opt = 0;
        for(i = 1; i <= N; i ++)
        {
            if(a[i] != 1) ++ not1;
            if(a[i] != 2) ++ not2;
            opt = std::min(opt, not1 - not2);
            ans = std::min(ans, not2 + opt + not3[i + 1]);
        }
        return ans;
    }
    void solve()
    {
        int i, ans = deal();
        for(i = 1; i <= N / 2; i ++) std::swap(a[i], a[N - i + 1]);
        ans = std::min(ans, deal());
        printf("%d\n", ans);
    }
    int main()
    {
        while(scanf("%d", &N) == 1)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    kafka学习3——单机伪集群(window版)
    (转)在阿里云 CentOS 服务器(ECS)上搭建 nginx + mysql + php-fpm 环境
    渗透测试工具sqlmap基础教程
    编译安装nginx后service nginx start 启动不了
    centos6.5上tomcat的安装
    centos6.5上安装淘宝tfs系统
    解决nagios登录不了的问题
    centos6.5上网络不通解决方法
    redis远程密码连接
    centos7上定时将mysql数据导出并且发送到指定的邮箱
  • 原文地址:https://www.cnblogs.com/staginner/p/2706920.html
Copyright © 2011-2022 走看看