zoukankan      html  css  js  c++  java
  • [离散化][区间DP]JZOJ 5770 可爱精灵宝贝

    日常黑Pokeman Go

    Description

    Branimirko是一个对可爱精灵宝贝十分痴迷的玩家。最近,他闲得没事组织了一场捉精灵的游戏。游戏在一条街道上举行,街道上一侧有一排房子,从左到右房子标号由1到n。
    刚开始玩家在k号房子前。有m个精灵,第i只精灵在第A[i]栋房子前,分值是B[i],以及它在T[i]秒内(含)存在,之后消失。Branimirko可以选择移动至相邻的房子,耗时1秒。抓住精灵不需要时间,精灵被抓住后消失。时间从第1秒开始。Branimirko能最多获得多少分值和。
     
     

    Input

    输入的第1行为三个正整数n,k,m。
    接下来m行描述精灵的信息,分别为A[i],B[i],T[i]。
     

    Output

    输出Branimirko能最多获得多少分值和。
     
     

    Sample Input

    10 5 4
    1 30 4
    3 5 7
    7 10 12
    9 100 23
     

    Sample Output

    115
     
     

    Data Constraint

    20%的数据:m≤10
    40%的数据:m≤20
    k≤n≤1000,m≤100,A[i] ≤N,B[i] ≤100,T[i] ≤2000,所有数为正整数。
     
     

    Hint

    很遗憾,它恰好不能抓住在一号房子前的精灵。
    如果T[1]改成5,答案就是145

    分析

    比赛的时候居然打了一个不知道什么鬼的居然离散了时间的DP

    正解区间DP,设f[l][r][t]为所用时间为t,经过了l~r,现在在r的最大分值,g[l][r][t],类似,不过在l

    预处理:离散化房屋编号

    然后从l~r向l-1~r或l~r+1转移

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <memory.h>
    using namespace std;
    int f[101][101][4001],g[101][101][4001];
    struct Elf {
        int a,b,t;
    }a[102];
    int n,m,k,mxt,bg;
    
    bool Cmp(Elf a,Elf b) {
        return a.a<b.a;
    }
     
    int main() {
        freopen("go.in","r",stdin);
        freopen("go.out","w",stdout);
        scanf("%d%d%d",&n,&k,&m);
        for (int i=1;i<=m;i++) scanf("%d%d%d",&a[i].a,&a[i].b,&a[i].t),mxt=max(mxt,a[i].t);
        a[0].a=k;a[0].b=0;a[0].t=1;
        sort(a,a+m+1,Cmp);
        for (int i=0;i<=m;i++)
        if (a[i].a==k&&a[i].t==1) {bg=i;break;}
        memset(f,-0x3f,sizeof f);
        memset(g,-0x3f,sizeof g);
        f[bg][bg][1]=g[bg][bg][1]=0;
        for (int t=1;t<=mxt;t++)
        for (int l=bg;l>=0;l--)
        for (int r=bg;r<=m;r++) {
            if (r<m) {
                f[l][r+1][a[r+1].a-a[r].a+t]=max(f[l][r+1][a[r+1].a-a[r].a+t],f[l][r][t]);
                f[l][r+1][a[r+1].a-a[l].a+t]=max(f[l][r+1][a[r+1].a-a[l].a+t],g[l][r][t]);
                if (a[r+1].a-a[r].a+t<=a[r+1].t)
                f[l][r+1][a[r+1].a-a[r].a+t]=max(f[l][r+1][a[r+1].a-a[r].a+t],f[l][r][t]+a[r+1].b);
                if (a[r+1].a-a[l].a+t<=a[r+1].t)
                f[l][r+1][a[r+1].a-a[l].a+t]=max(f[l][r+1][a[r+1].a-a[l].a+t],g[l][r][t]+a[r+1].b);
            }
            if (l>0) {
                g[l-1][r][a[r].a-a[l-1].a+t]=max(g[l-1][r][a[r].a-a[l-1].a+t],f[l][r][t]);
                g[l-1][r][a[l].a-a[l-1].a+t]=max(g[l-1][r][a[l].a-a[l-1].a+t],g[l][r][t]);
                if (a[r].a-a[l-1].a+t<=a[l-1].t)
                g[l-1][r][a[r].a-a[l-1].a+t]=max(g[l-1][r][a[r].a-a[l-1].a+t],f[l][r][t]+a[l-1].b);
                if (a[l].a-a[l-1].a+t<=a[l-1].t)
                g[l-1][r][a[l].a-a[l-1].a+t]=max(g[l-1][r][a[l].a-a[l-1].a+t],g[l][r][t]+a[l-1].b);
            }
        }
        int ans=0;
        for (int t=1;t<=mxt;t++)
        for (int l=bg;l>=0;l--)
        for (int r=bg;r<=m;r++)
        ans=max(ans,max(f[l][r][t],g[l][r][t]));
        printf("%d",ans);
        fclose(stdin);fclose(stdout);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    API
    MVC判断是否登录
    MVC收藏店铺
    MVC显示界面
    MVC登录
    MVC登录跳转到显示
    MVC退单
    MVC判断登录
    Oracle 千位符转换,及格式转换
    【转】Java 服务端 和 C# 客户端 实现 Socket 通信
  • 原文地址:https://www.cnblogs.com/mastervan/p/9433414.html
Copyright © 2011-2022 走看看