RQNOJ 99 配置魔药

来源:互联网 发布:saas数据库 编辑:程序博客网 时间:2024/04/29 18:45

RQNOJ 99 配置魔药

题目描述

传送门

在《Harry Potter and the Chamber of Secrets》中,Ron的魔杖因为坐他老爸的Flying Car撞到了打人柳,不幸被打断了,从此之后,他的魔杖的魔力就大大减少,甚至没办法执行他施的魔咒,这为Ron带来了不少的烦恼。这天上魔药课,Snape要他们每人配置一种魔药(不一定是一样的),Ron因为魔杖的问题,不能完成这个任务,他请Harry在魔药课上(自然是躲过了Snape的检查)帮他配置。现在Harry面前有两个坩埚,有许多种药材要放进坩埚里,但坩埚的能力有限,无法同时配置所有的药材。一个坩埚相同时间内只能加工一种药材,但是不一定每一种药材都要加进坩埚里。加工每种药材都有必须在一个起始时间和结束时间内完成(起始时间所在的那一刻和结束时间所在的那一刻也算在完成时间内),每种药材都有一个加工后的药效。现在要求的就是Harry可以得到最大的药效。
出自:宜昌一中

输入格式

输入文件的第一行有2个整数,一节魔药课的t(1≤t<≤500)和药材数n(1≤n≤100)。
输入文件第2行到n+1行中每行有3个数字,分别为加工第i种药材的起始时间t1、结束时间t2、(1≤t1≤t2≤t)和药效w(1≤w≤100)。

输出格式

输出文件medic.out只有一行,只输出一个正整数,即为最大药效。

样例

Input

7 41 2 104 7 201 3 23 7 3

Output

35

主要思路

此题可化简为选取线段的题目:即选取多条线段,任意两条线段不能有重合,求最大的分值。但此题由于有两个锅,所以较为麻烦。我的解决方法是:开一个三维dp数组,dp[k][i][j],描述选到第k个魔药,第一个锅在配第i种魔药,第二个锅在配第j种魔药时的最大分值(药效)。当转移第一个锅时,前两维相同,第二个锅时,第一维和第三维相同,这样就不会有重复,每次更新答案即可。转移过程如下:

此题与另一道题(RQNOJ 569 Milking Time)相比,更多了一层难度,对于选取线段的题目基础知识的讲解,欢迎来看我的另一篇博客:RQNOJ 569 Milking Time

代码如下

#include <iostream>#include <cstdio>#include <vector>#include <queue>#include <cmath>#include <algorithm>#include <cstdlib>#include <ctime>#include <map>#include <stack>#include <cstring>using namespace std;#define ll long longstruct nod{    int l,r,w;}a[105];int t,n,ans;int dp[105][105][105];bool cmp(nod x,nod y){    return x.l<y.l;}int main(int argc, char const *argv[]){    ios::sync_with_stdio(false);    cin>>t>>n;    for(int i=1;i<=n;i++)        cin>>a[i].l>>a[i].r>>a[i].w;    sort(a+1,a+n+1,cmp);    for(int k=1;k<=n;k++)        for(int i=0;i<k;i++)            for(int j=0;j<k;j++)            {                dp[k][i][j]=dp[k-1][i][j];                if(a[i].r<a[k].l)                    dp[k][k][j]=max(dp[k][k][j],dp[k-1][i][j]+a[k].w);                if(a[j].r<a[k].l)                    dp[k][i][k]=max(dp[k][i][k],dp[k-1][i][j]+a[k].w);                ans=max(ans,max(dp[k][k][j],dp[k][i][k]));            }    cout<<ans<<endl;    return 0;}