放水(8)

#include <iostream>
#include <algorithm>
using namespace std;

const int numLimit = 111;
struct st_floor
{
    int w, l, p;
};
struct st_sub
{
    int A, num;
};

struct st_floor floor_info[numLimit];
struct st_sub sub[numLimit];
bool visited[numLimit] = { false };
int N, bestcost, beststart;

void qk_pass(int start, int &mid, int stop)
{
    int tmp;
    struct st_sub key;
    tmp = rand() % (start - stop + 1) + start;
    key = sub[tmp];
    sub[tmp] = sub[start];
    while (start < stop)
    {
        while (start<stop && sub[stop].A>key.A)
            --stop;
        sub[start] = sub[stop];
        if (start < stop)
            ++start;
        while (start < stop && sub[start].A < key.A)
            ++start;
        sub[stop] = sub[start];
        if (start < stop)
            --stop;
    }
    mid = start;
    sub[start] = key;
}

void quciksort(int start, int stop)
{
    if (start < stop)
    {
        int mid;
        qk_pass(start, mid, stop);
        quciksort(start, mid - 1);
        quciksort(mid + 1, stop);
    }
}

void FindBestStartOfFloor()
{
    int subsum = 0, nowcost = 0, minus, i, p;
    for (i = 1; i <= N; ++i)
    {
        subsum += floor_info[i].w;
        sub[i].num = i;
        sub[i].A = subsum - floor_info[i].l;
        if (sub[i].A <= 0)
        {
            nowcost += floor_info[i].p;
            visited[i] = true;
        }
    }
    bestcost = nowcost;
    beststart = 1;
    quciksort(1, N);
    p = 1;
    minus = 0;
    for (i = 2; i <= N; ++i)
    {
        minus += floor_info[i-1].w;
        if (visited[i - 1])
            nowcost -= floor_info[i].p;
        while (p <= N && (sub[p].A - minus <= 0))
        {
            if (sub[p].num >= i && !visited[sub[p].num])
            {
                visited[sub[p].num] = true;
                nowcost += floor_info[sub[p].num].p;
            }
            ++p;
        }
        if (nowcost < bestcost)
        {
            beststart = i;
            bestcost = nowcost;
        }
    }
}

int main()
{
    cin >> N;
    if (N < numLimit)
    {
        for (int i = 1; i <= N; ++i)
            cin >> floor_info[i].w >> floor_info[i].l >> floor_info[i].p;
        FindBestStartOfFloor();
        int subsum = 0;
        for (int i = beststart; i <= N; ++i)
        {
            subsum += floor_info[i].w;
            if (subsum <= floor_info[i].l)
                printf("第%d层需要手动放水.\n", i);
        }
        
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值