我不想写背景

来源:互联网 发布:手机在哪里看网络制式 编辑:程序博客网 时间:2024/04/29 08:21

我不想写背景


题目描述

某巨魔去滑雪(没滑雪板),但他的技术并不精湛,在滑雪场里,每天会提供 S 门滑雪课。
i 节课始于时间 Mi ,上课的时长为 Li(只有在 Mi 时刻才能选择去上第 i 节课,其他时间不能选择上第 i 节课)。
上完第 i 节课后,巨魔的滑雪能力会变成 Ai. (注意:这个能力是绝对的,不是能力的增长值)。
巨魔买了一张地图,地图上显示了 N 个可供滑雪的斜坡,从第 i 个斜坡的顶端滑至底部所需的时长 Di,以及每个斜坡所需要的滑雪能力 Ci,以保证滑雪的安全性。
巨魔的能力必须大于等于这个等级,以使得他能够安全滑下。
巨魔可以用他的时间来滑雪,上课,或者在旁边菊花丛中练习箭法,但是他必须在 T 时刻离开滑雪场。
这意味着他必须在 T 时刻之前(或者 T 时刻)完成最后一次滑雪(或者上课)。
求巨魔在时间内最多可以完成多少次滑雪。
这一天开始的时候,他的滑雪能力为 1


输入格式

第一行 3 个数字,TSN
接下来 S 行,每行 3 个数字 MiLiAi
接下来 N 行,每行 2 个数字 CiDi


输出格式

一个整数,表示巨魔滑雪的最大次数。


样例输入

10 1 2
3 2 5
4 1
1 3


样例输出

6


样例解释

0时刻,选择在第1个斜坡上滑雪,时间花费3。
3时刻,选择上第1节课。滑雪技术提高到5,时间花费2。
5时刻,选择在第2个斜坡上滑雪,时间花费1。
6时刻,选择在第2个斜坡上滑雪,时间花费1。
7时刻,选择在第2个斜坡上滑雪,时间花费1。
8时刻,选择在第2个斜坡上滑雪,时间花费1。
9时刻,选择在第2个斜坡上滑雪,时间花费1。
10时刻,收队了。
总滑雪次数:6


数据范围

50% 的数据:1N,T1000
100% 的数据:1N,T100001S,Ai,Ci1001Mi,Li,Di10000


Solution

f[i][j] 表示当前等级为 i,时刻为 j 的最多滑雪次数。
转移方程就很容易推了。


Code

#include <iostream>#include <cstdio>#include <algorithm>#include <queue>using namespace std;int oo=(2147483647);struct answer{    int i,j,k;    answer(int a,int b,int c){        i=a;        j=b;        k=c;    }    bool operator > (const answer num)const{        if(i!=num.i)return i>num.i;        if(j!=num.j)return j>num.j;        if(k!=num.k)return k>num.k;    }};struct object{    int l,t,v;    object(){        l=t=v=oo;    }};struct snow{    int c,d;    snow(){        c=d=oo;    }};inline int Max(int a,int b){    return a>b?a:b;}inline int in(){    char ch;    int x=0,flag=1;    ch=getchar();    while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();    if(ch=='-'){flag=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x;}int t,s,n,rn,ans;int maxn;object o[10010];snow w[10010];priority_queue<answer,vector<answer>,greater<answer> >S;bool cmp(object a,object b){    return a.l<b.l;}bool cmp2(snow a,snow b){    return a.c<b.c; }void prework(){    scanf("%d%d%d",&t,&s,&n);                                           rn=n;                                                       for(int i=1;i<=s;i++){        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        if(x+y<=t){            o[i].l=x;            o[i].t=y;            o[i].v=z;            maxn=Max(maxn,o[i].v);        }        else            o[i].l=oo;    }    for(int i=1;i<=n;i++){        scanf("%d%d",&w[i].c,&w[i].d);        if(w[i].c>maxn){w[i].c=oo;rn--;}    }    for(int i=1;i<n;i++)        for(int j=i+1;j<=n;j++)if(w[j].c!=oo&&w[i].c!=oo){            if(w[i].c<=w[j].c&&w[i].d<=w[j].d){w[j].c=oo;rn--;}            if(w[i].c>=w[j].c&&w[i].d>=w[j].d){w[i].c=oo;rn--;}        }    for(int i=0;i<=t;i++)        S.push(answer(i,1,0));    sort(o+1,o+s+1,cmp);    sort(w+1,w+n+1,cmp2);}void mainwork(){    int now=1;    while(!S.empty()){        answer nos=S.top();        S.pop();        while(!S.empty()&&nos.i==(S.top()).i&&nos.j==(S.top()).j){            nos.k=(S.top()).k;            S.pop();        }        while(o[now].l==nos.i){            if(o[now].v>nos.j)                S.push(answer(nos.i+o[now].t,o[now].v,nos.k));            now++;        }        for(int k=1;k<=rn;k++){            if(w[k].c>nos.j)break;            if(nos.i+w[k].d<=t)                S.push(answer(nos.i+w[k].d,nos.j,nos.k+1));        }        if(ans<nos.k)ans=nos.k;    }}void endwork(){    printf("%d",ans);}int main(){    freopen("wtf.in","r",stdin);    freopen("wtf.out","w",stdout);    prework();                                      mainwork();    endwork();    return 0;}
0 0
原创粉丝点击