zoukankan      html  css  js  c++  java
  • 水站 (二分)

    题目大意

    • 已知有一个n层的水站:
      • Wi表示未操作之前第i层的已有水量;
      • Li表示第i个水站能够维持或者储存的水的重量;
      • Pi表示在第i层进行减压放水操作所需的费用.
      • 被压减放水层所储存的所有水都将流向下一层。如果第i层的水量比Li大,则这一层也会(自动)减压(不需要任何费用)。
    • 现在想要使最后一层减压(第n级),求最少的花费。这个任务现在交给了你。

    输入格式

    • 每个输入的第一行包含一个自然数n(1 =< n <= 150000)
    • 接下来n行每行包含3个数Wi,Li,Pi。

    输出格式

    • 第一行输出所需的最小费用
    • 第二行若干个整数,从小到大输出必须减压的层的编号。

    样例

    样例输入

    3
    1000 1000 1
    0 1000 2
    2 10 100
    

    样例输出

    3
    1 2
    

    算法分析

    • 模拟很好想吧 首先先来看一个事实: 如果当前节点i是第一个花钱把它减压的 那么从i到n一定所有的节点都减压了 因为如果在中间的某个节点没有减压的话 那么它前面的减压花费相当于白给
    • 但是模拟会T 所以我们要准备想正解了
    • 如果假设当前节点为k 在节点k之前有一个节点i 如果从i之前开始那么k不需要主动减压 从i之后开始需要主动减压(i越靠前到k处的水就越多 很容易 自己想)
    • 而关于这个节点的位置我们可以二分查找
    • 然后我们定义 ci 为从第 i 层开始放水一直放到第 n 层所需的费用. 考虑第 k 层的强制放水花费会对整个 ⟨ci⟩ 产生什么样的影响. 显然有当且仅当从第 i 层到第 k 层的总水量都不足以使第 k 层自动减压时 ci 中会包含第 k 层的强制放水费用. 因为当 k 不变时总水量随着 i 的减少而单调增加, 所以合法的 i 必然是比 k 小的连续一段, 二分找到最小的 i , 把最小的 i 到 k 之间的所有 ci 都加上 k 的花费即可. 而这个操作可以通过简单的前缀和解决. 总时间复杂度是 O(nlogn).

    代码展示

    
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 15e4+10;
    int n;
    int w[maxn],l[maxn],p[maxn];
    int sum[maxn],v[maxn];
    int now,ans = 0x3f3f3f3f;
    
    int main(){
    	scanf("%d",&n);
    	for(int i = 1;i <= n;++i){
    		scanf("%d%d%d",&w[i],&l[i],&p[i]);
    		sum[i] = sum[i-1] + w[i];
    	}
    	for(int i = 1;i <= n;++i){
    		int L = 1,R = i;
    		while(L < R) {
    			int mid = (L + R) >> 1;
    			if(sum[i] - sum[mid - 1] <= l[i])R = mid;
    			if(sum[i] - sum[mid - 1] > l[i])L = mid + 1;
    		}
    		v[R] += p[i];
    		v[i+1] -= p[i];
    	}
    	for(int i = 1;i <= n;++i){
    		v[i] += v[i-1];
    		if(ans > v[i])ans = v[i],now = i;
    	}
    	printf("%d
    ",ans);
    	for(int i = now;i <= n;++i)
    		if(sum[i] - sum[now - 1] <= l[i])printf("%d ",i);
    	return 0;
    }
    
    
    如初见 与初见
  • 相关阅读:
    机器学习中数据缺失的处理及建模方法
    小样本学习(Few-Shot Learning)
    常见文本相似度计算法
    【FPGA ZYNQ Ultrascale+ MPSOC教程】33.BRAM实现PS与PL交互
    【紫光同创国产FPGA教程】【第十章】DDR3读写测试实验
    【紫光同创国产FPGA教程】【第九章】HDMI编程测试实验
    【紫光同创国产FPGA教程】【第八章】SD卡读写实验
    【紫光同创国产FPGA教程】【第七章】I2C接口EEPROM实验
    【紫光同创国产FPGA教程】【第六章】PDS下按键消抖实验
    【紫光同创国产FPGA教程】【第五章】串口收发实验
  • 原文地址:https://www.cnblogs.com/HISKrrr/p/13325299.html
Copyright © 2011-2022 走看看