牛客2021年度训练联盟热身训练赛第八场-L

加权的线段覆盖

题目
What’s Mine is Mine
链接:https://ac.nowcoder.com/acm/contest/15644/L
来源:牛客网

The hot new video game “Mining Simulator” has just been released. In the game, rare earth mineral ores appear at certain times and you can mine them when they appear. After mining, you can later turn in the minerals for money. The quantity of mineral available during an appearance is proportional to the duration of the appearance and the price per unit of each mineral is decided beforehand.

The game contains a geological sensor that determines times when mineral ores will appear during a given day and at the beginning of each day you have a price list for each mineral. Assuming you mine out the mineral in exactly the amount of time that it is available, you cannot partially mine minerals (you must either not mine any of a given occurrence or mine all of it) and you can only mine one ore occurrence at a time.

Given a list of the prices of ݉m minerals and n ore occurrences during a day, write a program to output the maximum amount of money you can earn from mining on that day. The mineral amount is the appearance time (end time – start time). You can mine an ore right after finishing the previous mining. In other words, one mined-ore’s end time can be same as another mined-ore’s start time. In the case depicted in Figure L.1, if you choose the mineral of type 1 that appears at time 2 and disappears at time 5, then the mineral amount is 5 − 2 = 3 and you earn 3 × 2 = 6. Next, if you choose the mineral of type 2 that appears at time 7 and disappears at time 11, then the mineral amount is 11 − 7 = 4 and you earn 4 × 3 = 12. Therefore, you earn 18 in total.

输入描述:
Your program is to read from standard input. The input starts with a line containing two integers, ݉m and n (1 ≤ m ≤100, 1 ≤n ≤ 10,000), where ݉m is the number of types of minerals and n is the number of ore occurrences during the day. The mineral types are labeled from 1 to ݉m. The following ݉m lines contain a single integer corresponding to the price of one unit of the i-th mineral type on that day (the price is between 1 and 10,000). The following n lines represent ore occurrences. Each line contains three integers, s, e݁, t where s is the start time, e is the end time and t is the mineral type in each ore occurrence with 0 < s < e < 15,000 and 1 ≤ t ≤ m. The amount of mineral at each occurrence is ݁e - s.
输出描述:
Your program is to write to standard output. Print exactly one line. The line should contain the maximum amount of money that can be earned on that day.

The following shows sample input and output for three test cases.
示例1
输入
复制
2 5
2
3
2 5 1
4 5 2
4 6 1
7 11 2
6 10 1
输出
18
示例2
输入
3 5
2
3
1
1 4 1
3 6 3
5 8 2
7 10 1
9 12 2
输出
24
示例3
输入
5 7
1
2
3
4
5
1 5 2
3 8 1
2 4 3
3 9 2
4 10 5
7 11 4
5 7 3
输出
36

大概题意是给定n个不同的小区间总共有m种赋值,而一段区间内只能赋一个值,小区间连续不可中断,求所有区间值加起来的最大值。(1 ≤ m ≤100, 1 ≤n ≤ 10,000)

用一维dp求解
dp[ i ] 表示1 - i 区间的最大值
递推式 : dp[ i ] = max(dp[i - 1] , dp[i - time] + x) x表示 i-time – i 区间的值

#include<bits/stdc++.h>
using namespace std;

struct stu
{
    int st,en;//起点,终点
    int x;
};
stu p[10005];
bool cmp(stu a,stu b)//结构体排序
{
    if(a.st != b.st)
        return a.st < b.st;
    else
        return a.en < b.en;
}

int m,n,maxx = 0;
int va[105],dp[100010];

int main()
{
    cin>>m>>n;
    for(int i = 1; i <= m; i ++ )
        cin>>va[i];
    for(int i = 1; i <= n; i ++ )
    {
        cin>>p[i].st>>p[i].en>>p[i].x;
        p[i].x = va[p[i].x];//单位长度的价值
        maxx = max(p[i].en,maxx);//所有区间最右边界
    }
    sort(p+1,p+1+n,cmp);
    int ans = 1;
    for(int i = 1; i <= maxx; i ++ )
    {
        dp[i] = max(dp[i - 1],dp[i]);//第i个长度不做处理的情况
        while(i == p[ans].st)、、存在可处理区间
        {
            dp[p[ans].en] = max(dp[p[ans].en],dp[i] + (p[ans].en - p[ans].st) * p[ans].x);//递推
            ans ++ ;
        }
    }
    cout<<dp[maxx];
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值