zoukankan      html  css  js  c++  java
  • CodeForces 1290A Mind Control(思维)

    题目链接OvO

    题目大意

      有一个长度为(n)的序列,每个人都能拿走序列中的第一个数或者最后一个数,你可以指定(k)个人拿的顺序,问第(m)个人拿的数最大是多少。

    分析

      既然这个题的数据不大那么就尽可能的往暴力的方面想,有没有办法列举出所有的情况呢?先看一下下图:
      
      可以很容易的看出,对于选定(k)个之后可选的区间会是一个长度为(n-k)的滑块,我们要做的就是枚举出滑块里面所有的情况,再让滑块移动,改变区间,再进行枚举,那么滑块里面是什么情况呢?
      
      在黑滑块里面还有一个红色子滑块,这个子滑块的头尾两个数之间的最大值就是每种情况要选的数(因为要最优所以选最大的)。而这个滑块可以移动的范围就是选完(k)个之后到(m)之间的那几个数,因为这几个选择是不能指定的,所以对于一个固定的黑滑块来说,其最优的情况就是所有最优解的最小值。而对于整个序列来说,因为前(k)个人是可以指定的,所以最优解就是所有最优解最小值中的最大值。

    具体实现

      实现上没什么好说的,主要是计算方面可能有点问题。首先需要注意的是如果(k)大于(m-1)的话取(m-1)就行了,再大了也不会对结果又影响而且实现起来还会带来麻烦。然后就是注意一下计算各个滑块长度与可移动距离的大小就行了。

    代码

    const int maxn = 1e4+10;
    int arr[maxn];
    int main(void) {
        int t;
        cin >> t;
        while(t--) {
            int n, m, k;
            cin >> n >> m >> k;
            for (int i = 1; i<=n; ++i) cin >> arr[i];
            if (k>=m) k = m-1;
            int ans = -1, len1 = n-k, len2 = len1-(m-k-1);
            for (int i = 1; i<=k+1; ++i) {
                int tmp = INF;
                for (int j = i; j<=i+m-k-1; ++j)
                    tmp = min(tmp, max(arr[j], arr[j+len2-1]));
                ans = max(ans, tmp);
            }
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    十月二十七学习报告
    十月二十六学习报告
    十月二十五学习报告
    十月二十四学习报告
    十月二十三学习报告
    十月二十二学习报告
    十月二十一学习报告
    十月十九学习报告
    十月十七学习报告
    十月十六学习报告
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12787918.html
Copyright © 2011-2022 走看看