zoukankan      html  css  js  c++  java
  • bzoj3728: PA2014Final Zarowki

     

    Description

    有n个房间和n盏灯,你需要在每个房间里放入一盏灯。每盏灯都有一定功率,每间房间都需要不少于一定功率的灯泡才可以完全照亮。
    你可以去附近的商店换新灯泡,商店里所有正整数功率的灯泡都有售。但由于背包空间有限,你至多只能换k个灯泡。
    你需要找到一个合理的方案使得每个房间都被完全照亮,并在这个前提下使得总功率尽可能小。

    Input

    第一行两个整数n,k(1<=k<=n<=500000)。
    第二行n个整数p[i](1<=p[i]<=10^9),表示你现有的灯泡的功率。
    第三行n个整数w[i](1<=w[i]<=10^9),表示照亮每间房间所需要的最小功率。

    Output

    如果无法照亮每间房间,仅输出NIE。
    否则输出最小的总功率。

    Sample Input

    6 2

    12 1 7 5 2 10

    1 4 11 4 7 5

    Sample Output

    33

    HINT

    解释:将2和10换成4和4。配对方案为1-1,4-4,4-4,5-5,7-7,11-12。

    /*题面选最小。。。

        Multiset+贪心可水,原理就是小的灯泡能用则用,不能用的保留,最后再用k次机会滑稽掉剩下的。再有剩余的可以把之前用的灯泡和房间差值变成0来减小。

        这个堆+贪心啊,我承认我傻=-=。想了好久才明白。

        首先对功率和房间从大到小排序,排完以后开始贪心。把符合当前房间条件的所有的灯泡都放进堆里(这个堆也保留之前房间剩余的),在里面选个最小的来提供给房间。但是!当这个堆里啥玩意都没有,即对于这个垃圾房间没有灯泡给它,我们就用一次换灯泡的机会,再给ans加上房间的需求,然后继续即可以。

        然后我就方了,为什么不用改别的灯泡呢=-=,我这个蒟蒻百思不得其解=-=。因为我们使用这次机会以后,首先,对于以后的数据,扩大了可选择的范围(因为灯泡里接下来的最大值被保留了),其次由于不存在可以给这个房间提供的灯泡(因为有的之前给别的了,如果别的被替换,还是得使用一次机会)这次机会必须得用掉,然后对于某个可能被替换掉的灯泡,我相当于把它延后选择,即先把接下来可用灯泡都用掉,最后一定会多剩余一个灯泡(如果有小到没法用的自然剩余,要是较小的在某个房间可用,便会剩下一个大的)。

        综上而言,这个贪心是正确的,因为它没有导致答案变大(使用最小),且保证了可解(保留剩下最大)。*/

     1 #include<cstdio>
     2 #include<queue>
     3 #include<algorithm>
     4 using namespace std;
     5 int n,k;
     6 const int N=500500;
     7 priority_queue<int > red;
     8 priority_queue<int,vector<int>,greater<int> > q;
     9 long long ans;
    10 int p[N],w[N];
    11 inline bool m_s(int a,int b){
    12     return a>b;
    13 }
    14 int main(){
    15     scanf("%d%d",&n,&k);
    16     for(int i=1;i<=n;i++)   scanf("%d",p+i);
    17     for(int i=1;i<=n;i++)   scanf("%d",w+i);
    18     sort(p+1,p+1+n,m_s);sort(w+1,w+n+1,m_s);
    19     for(int i=1,j=1;i<=n;i++){
    20         while(p[j]>=w[i])   q.push(p[j++]);
    21         if(!q.empty()){
    22             ans+=q.top();
    23             red.push(q.top()-w[i]);q.pop();continue;
    24         }
    25         k--,ans+=w[i];
    26         if(k<0) {printf("NIE
    ");return 0;}
    27     }
    28     while(k--)ans-=red.top(),red.pop();
    29     printf("%lld
    ",ans);
    30 }
  • 相关阅读:
    C# vb实现浮雕特效滤镜效果
    一张图看懂SharpImage
    C#控制操控操作多个UVC摄像头设备
    C#读写修改设置调整UVC摄像头画面-缩放
    继承多态绕点 Java篇
    继承多态绕点 C#篇
    lock关键字理解
    关于C#迭代器
    关于排列组合中组合结果
    C#与Java中相等关系
  • 原文地址:https://www.cnblogs.com/Troywar/p/7242207.html
Copyright © 2011-2022 走看看