zoukankan      html  css  js  c++  java
  • HDU-5777 domino

    题目大意:

    小白在玩一个游戏。桌子上有n张多米诺骨牌排成一列。它有k次机会,每次可以选一个还没有倒的骨牌,向左或者向右推倒。每个骨牌倒下的时候,若碰到了未倒下的骨牌,可以把它推倒。小白现在可以随意设置骨牌的高度,但是骨牌高度为整数,且至少为1,并且小白希望在能够推倒所有骨牌的前提下,使所有骨牌高度的和最小。

    解题思路:

    官方题解首先骨牌只要考虑都往右推,其次能带倒骨牌的前提是高度大于等于距离+1。所以如果推一次,那么就是骨牌高度=离下一块骨牌距离+1. 把第一块左边距离设为无穷大,能推nk次,那么就是找nk块左边距离最大的向右推倒即可,所以只需要排序找到前nk-1大的距离。 有个小trick,推的次数可能大于骨牌数量 复杂度 O(nlogn)

    我的思路首先每个骨牌的高度至少为1,而且每个骨牌如果要将相邻的骨牌推倒,必须要比相邻距离要大,那么可以假设每个骨牌现在高度都是1。那么现在的问题就是需要用最短的距离来覆盖1-n的区间,但是并不是每个区间都必须要覆盖掉,最长的k-1个区间可以不被覆盖,那么剩下的覆盖区间只需要一次累加就可以了。时间复杂度为排序或者优先队列的O(nlogn)

    代码:

    #include <queue>
    #include <cstdio>
    using namespace std;
    typedef long long LL;
    int main(){
        int t, n, k, x;
        scanf("%d", &t);
        while(t--){
            scanf("%d%d", &n, &k);
    
            LL ans = n;
            priority_queue<int> q;
            while(!q.empty()) q.pop();
            for(int i = 1; i < n; ++i){
                scanf("%d", &x);
                q.push(x);
            }
    
            while(!q.empty()){
                x = q.top();
                q.pop();
                if(k > 1) {--k; continue;}
                ans += x;
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }


  • 相关阅读:
    easyExcel入门
    UML-从需求到设计--迭代进化
    UML-操作契约总结
    102. Binary Tree Level Order Traversal
    98. Validate Binary Search Tree
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
    94. Binary Tree Inorder Traversal
    84. Largest Rectangle in Histogram
    92. Reverse Linked List II
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179432.html
Copyright © 2011-2022 走看看