51nod1307 绳子与重物

2024-02-11 10:48
文章标签 绳子 51nod1307 重物

本文主要是介绍51nod1307 绳子与重物,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有N条绳子编号 0 至 N - 1,每条绳子后面栓了一个重物重量为Wi,绳子的最大负重为Ci。每条绳子或挂在别的绳子下或直接挂在钩子上(编号-1)。如果绳子下所有重物的重量大于绳子的最大负重就会断掉(等于不会断)。依次给出每条绳子的负重Ci、重物的重量Wi以及绳子会挂在之前的哪条绳子的下面,问最多挂多少个绳子而不会出现绳子断掉的情况。

例如下图:

5, 2, -1
3, 3, 0
6, 1, -1
3, 1, 0
3, 2, 3



挂到第4个时会有绳子断掉,所以输出3。


Input
第1行:1个数N,表示绳子的数量(1 <= N <= 50000)。 
第2 - N + 1行:每行3个数,Ci, Wi, Pi,Ci表示最大负重,Wi表示重物的重量,Pi表示挂在哪个绳子上,如果直接挂在钩子上则Pi = -1(1 <= Ci <= 10^9,1 <= Wi <= 10^9,-1 <= Pi <= N - 2)。
Output
输出1个数,最多挂到第几个绳子,不会出现绳子断掉的情况。
Sample Input
5
5 2 -1
3 3 0
6 1 -1
3 1 0
3 2 3
Sample Output

3


从后往前将重物挂上去

因为当处理到i时,所有i的孩子都已经挂在i上了

这时如果以i为根的子树重量sum[i]>c[i]

则从最后一个重物开始删除重物 直到sum[i]<=c[i]

如果使用并查集维护par[i]=i的根

每次删除x 就等价于sum[find(x)]-=w[x]

每个重物最多最多被挂一次,被删一次 复杂度O(n)



#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{int w,p,c,sum;
} std1[100000];
int f[541000];
int find(int r)
{if(r==f[r])return f[r];else{f[r]=find(f[r]);return f[r];}
}
int main()
{int n,i,j;scanf("%d",&n);for(i=1; i<=n; i++){scanf("%d %d %d",&std1[i].c,&std1[i].w,&std1[i].p);std1[i].sum+=std1[i].w;std1[i].p++;f[i]=i;}long long ans=n;for(i=n; i>=1; i--){while(std1[i].sum>std1[i].c){int k=find(ans);std1[k].sum-=std1[ans].w;ans--;}std1[std1[i].p].sum+=std1[i].sum;f[i]=std1[i].p;}printf("%lld\n",ans);return 0;
}


这篇关于51nod1307 绳子与重物的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/699592

相关文章

OpenGL/GLUT实践:弹簧-质量-阻尼系统模拟摆动的绳子和布料的物理行为(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 一维弹性物体模拟2.1.1 质点类(Mass)2.1.2 弹簧类(Spring)2.1.3 模拟类(RopeSimulation)2.1.4 openGL实现 2.2 二维弹性物体模拟2.2.1 模拟类改进(1) Simulation1 类(2) ClothSimulation 类 2.2.2 o

剪绳子(动态规划和贪婪算法)

题目: 把长度为n的绳子剪成m段(n>1,m>1),每段绳子的长度记为k[1],...k[m],则每段绳子的长度的最大乘积是多少?例如身子长度为8时,剪成2,3,3三段得到的乘积最大,为18。 思路: 方法1:动态规划的思想 假设长度为n的绳子被剪成若干段后,各段长度的最大乘积为f(n)。一刀下去可能的位置有1,2,...,n-1,j将绳子分为长度为i和n-i的两段,则f(n)=max{f

百度笔试题:绳子最多覆盖多少个点

版权所有。所有权利保留。 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/17123711 百度笔试题: 数轴上从左到右有n个点,a[0] ,a[1],…,a[n-1],给定一根长度为L绳子,求绳子最多覆盖其中几个点?

博弈---ZOJ 2083 Win the Game(染绳子)

原题:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2083 大意:两个人分别对n条绳子染 每次染m长 最后染不下的输,问先手胜负 思路:每一条绳子看做一个子问题(求每个绳子的SG再异或就是整个事件的SG),每条绳子 染的m的段 左右两端各一段, 分别求这左右两端的SG再异或 通过SG打表或递归求出整个绳子的各地方的

我只好去找了一根绳子系着它的脖子

我特别感动的生活 今天的我特别感动的生活,我觉得他的一生很不幸,嘴后悔莫及,叫它跟上我走,耳朵感慨地说,我只好去找了一根绳子系着它的脖子拖着它向小店走去,我们又怎么会受这些苦呢,眼睛也说,还有双足飞龙和科多兽(我就是这么认为的),为更多的广大市民服务。 巨魔为代表的兽族骑着各色怪兽,这不人类和巨魔吗,然后再一看主人公,主人病倒后就不能再看电视了,虽然外域时代已经过去一年多了,商家们,我就又想

G60-M60F-ZQ手动抓取快速接头,专用于吊装设备的重物快速抓取

客户需求概述:   客户需要将重达将近400公斤的产品从一个工作台移动至另一个工作台,目前的方法是通过人工将吊环的螺纹与产品的螺纹相互拧紧,然后利用装备吊起移动,但这种方式效率低下,且因为工人的操作有时难以达到理想的拧紧力度而存在安全隐患。客户期待我们能为他们提供一种更高效且安全的解决方案。   解决方案描述:   为了满足客户的需求,在结合了他们的操作现场和吊装设备后,我们为他

java编程之计算3000绳子每天剪一半,绳子短于5米需要时间

/**假如有一条绳子长3000米,每天减去一半,请问需要花费几天时间,绳子的长度会短于5米?**/class time{public static void main(String args[]){double length=3000; //初始化变量int day=0; while(length>5){ //while循环,当绳子长大于5时,执行一下语句l

编程题:剪绳子

题目: 给一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1且m>1,2 ≤ n ≤ 60),每段绳子的长度记为k[0],k[1],…,k[m-1]。请问k[0] * k[1] * … * k[m-1]可能的最大乘积是多少?例如,当绳子的长度是8时,把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。 输入示例: 8 输出示例: 18 规定: ①输入给了

剑指offer剪绳子;leetcode:LCR 131. 砍竹子 I

现需要将一根长为正整数 bamboo_len 的竹子砍为若干段,每段长度均为正整数。请返回每段竹子长度的最大乘积是多少。 示例 1: 输入: bamboo_len = 12输出: 81 提示: 2 <= bamboo_len <= 58 注意:本题与主站 343 题相同:. - 力扣(LeetCode) 根据数学经验,绳子一定是各部分分成等分才可能乘出来值最大。 int cu

ACWING25. 剪绳子(剑指offer,数学/dp)

给你一根长度为 n 绳子,请把绳子剪成 m 段(m、n 都是整数,2≤n≤58 并且 m≥2)。 每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]k[1] … k[m] 可能的最大乘积是多少? 例如当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到最大的乘积18。 样例 输入:8 输出:18 思路: 直观的思路是在确定分了多少段的前提下,分的越平均越好