zoukankan      html  css  js  c++  java
  • 51nod 1307绳子和重物

    题目来源: Codility
    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     收藏
     关注
    有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个数,最多挂到第几个绳子,不会出现绳子断掉的情况。
    Input示例
    5
    5 2 -1
    3 3 0
    6 1 -1
    3 1 0
    3 2 3
    Output示例
    3

    思路:1.二分,二分枚举最多能挂到第k个绳子,从第k个往第一个推,若发现当前可以绳子可以承载下所有重物则将k增大,否则将k减小。
       2.并查集,并查集自底向上维护每一个绳子,若当前绳子挂的负重大于承重则从最后一个重物开始往前删,直到负重小于承重,这样下去等挂到根节点的时候所有的重物都已经挂完了,剩下没有删掉的个数即为最多的个数

    二分:
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 typedef long long LL;
     7 const int maxn = 50005;
     8 struct node {
     9     LL w, c, pre, cost;
    10 }e[maxn];
    11 LL n;
    12 void reset()
    13 {
    14     for (int i = 0; i <= n; i++)
    15         e[i].cost = 0;
    16 }
    17 int main()
    18 {
    19     ios::sync_with_stdio(false);
    20     while (cin >> n) {
    21         for (int i = 1; i <= n; i++) {
    22             cin >> e[i].c >> e[i].w >> e[i].pre;
    23             e[i].pre++;
    24         }
    25         int l = 1, r = n; bool flag;
    26         while (l <= r) {
    27             int mid = (l + r) >> 1;
    28             flag = true;
    29             reset();
    30             for (int i = mid; i >= 1; i--) {
    31                 e[i].cost += e[i].w;
    32                 if (e[i].cost > e[i].c) {
    33                     flag = false; break;
    34                 }
    35                 e[e[i].pre].cost += e[i].cost;
    36             }
    37             if (flag) l = mid + 1;
    38             else r = mid - 1;
    39         }
    40         cout << r << endl;
    41     }
    42     return 0;
    43 }

    并查集:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 const int maxn = 50005;
     7 typedef long long LL;
     8 struct Task {
     9     int w, c, pre, cost;
    10 }e[maxn];
    11 int n, f[maxn];
    12 int Find(int x)
    13 {
    14     if (f[x] != x)
    15         f[x] = Find(f[x]);
    16     return f[x];
    17 }
    18 int main()
    19 {
    20     ios::sync_with_stdio(false);
    21     while (cin >> n) {
    22         for (int i = 1; i <= n; i++) {
    23             cin >> e[i].c >> e[i].w >> e[i].pre;
    24             e[i].cost += e[i].w; e[i].pre++;
    25             f[i] = i;
    26         }
    27         int ans = n;
    28         for (int i = n; i >= 1; i--) {
    29             while (e[i].cost > e[i].c) {
    30                 int tmp = Find(ans);
    31                 e[tmp].cost -= e[ans].w;
    32                 ans--;
    33             }
    34             e[e[i].pre].cost += e[i].cost;
    35             f[i] = e[i].pre;
    36         } 
    37         cout << ans << endl;
    38     }
    39     return 0;
    40 }
  • 相关阅读:
    开源跳板机(堡垒机)系统 Jumpserver安装教程(带图文)
    运维自动化管理服务器 CheungSSH
    代码托管服务平台GitHub
    Java 博客系统 Tale
    基于代码生成器的快速开发平台 JEECG
    中文企业云操作系统 CecOS
    Python基础学习(一)之Python的概述与环境安装
    Python3.x安装教程及环境变量配置
    PHP Primary script unknown 终极解决方法
    正则表达式备忘录-Regular Expressions Cheatsheet中文版
  • 原文地址:https://www.cnblogs.com/wangrunhu/p/9470676.html
Copyright © 2011-2022 走看看