我不想寫背景

我不想寫背景


題目描述

某巨魔去滑雪(沒滑雪板),但他的技術並不精湛,在滑雪場裏,每天會提供 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章