BZOJ 1571 DP

思路:
预处理出在能力值为i的时候 滑雪一次的最小时间

f[i][j]表示i时间 j的能力值 最多的滑雪次数

我先用vector 把课程按起点push进去

1.

for(int k=0;k<vec[i].size();k++){
        f[i+vec[i][k].l][vec[i][k].a]=max(f[i+vec[i][k].l][vec[i][k].a],f[i][j]);
    }

上课

2.
f[i+1][j]=max(f[i][j],f[i+1][j]);
喝一杯可可汁

3.
f[i+land[j]][j]=max(f[i+land[j]][j],f[i][j]+1);
滑雪

//By SiriusRen
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int t,s,n,land[105],f[20005][105];
struct Course{int m,l,a;}course[10005];
struct Land{int c,d;}jyl;
vector<Course>vec[10005];
int main(){
    memset(land,0x3f,sizeof(land));
    scanf("%d%d%d",&t,&s,&n);
    for(int i=1;i<=s;i++){
        scanf("%d%d%d",&course[i].m,&course[i].l,&course[i].a);
        vec[course[i].m].push_back(course[i]);
    }
    for(int i=1;i<=n;i++){
        scanf("%d%d",&jyl.c,&jyl.d);
        land[jyl.c]=min(land[jyl.c],jyl.d);
    }
    for(int i=1;i<=100;i++)land[i]=min(land[i],land[i-1]);
    memset(f,-1,sizeof(f));
    f[0][1]=0;
    for(int i=0;i<=t;i++){
        for(int j=1;j<=100;j++){
            if(f[i][j]==-1)continue;
            for(int k=0;k<vec[i].size();k++){
                f[i+vec[i][k].l][vec[i][k].a]=max(f[i+vec[i][k].l][vec[i][k].a],f[i][j]);
            }
            f[i+1][j]=max(f[i][j],f[i+1][j]);
            f[i+land[j]][j]=max(f[i+land[j]][j],f[i][j]+1);
        }
    }
    for(int i=1;i<=100;i++)f[t][1]=max(f[t][1],f[t][i]);
    printf("%d\n",f[t][1]);
}

这里写图片描述

posted @ 2016-10-27 19:48  SiriusRen  阅读(157)  评论(0编辑  收藏  举报