zoukankan      html  css  js  c++  java
  • 洛谷P1156 垃圾陷阱题解

       本题是一个背包问题,这点可以根据观察题目性质得出。背包问题的难点在于如何找出重量和价值。

       本题中一共有多个变量:1. 时间 2.高度 3.能量。所以我们需要分析如何从中找到可以进行转移的状态量

       我们所需要求的是跳出井口的最短时间,但是我们可以发现,因为我们必须按垃圾掉落顺序来处理垃圾,所以一旦处理到某个垃圾使得他的高度达到d,那么这个垃圾掉落的时间就是答案,所以时间变量可以忽视

       那么我们自然而然的可以把剩下的两个变量当做背包问题的重量和价值,我们可以设f[i][j],其中i表示前i个物品,j表示高度,而f[i][j]表示前i个物品在高度为j时总能量的最大值。这里可以利用Acwing闫老师的动态规划分析法得出,同时在这里安利一下Acwing网站,十分不错。

       本题的状态表示已经可以得出,那么现在只需要进行状态转移,其实这里可以使用滚动数组优化,但是优化并没有必要,因为数据范围并不大,而且容易出错。

       代码中有其他注释,请食用,另外,本队的赵文泽大佬说要疯狂学习,明年区域赛带我拿银牌,在这里先记录一下hhh:

        

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<functional>
    #include<string>
    #include<algorithm>
    #include<iostream>
    #include<set>
    #include<vector>
    #include<queue>
    #include<cstdlib>
    using namespace std;
    const int N=110;
    const int inf=0x3f3f3f3f;
    int f[N][N];
    struct node{
        int t;
        int h;
        int f;
    }s[110];
    bool cmp(node a,node b){
        return a.t<b.t;
    }
    int main(){
        int i,j,k;
        int n,m;
        cin>>n>>m;
        for(i=1;i<=m;i++){
            cin>>s[i].t>>s[i].f>>s[i].h;
        }
        sort(s+1,s+m+1,cmp);//按照时间顺序排序 
        f[0][0]=10;
        //传统背包中的放与不放,用加血还是加重量表示 
        for(i=1;i<=m;i++){
            for(j=0;j<=n;j++){
              if(f[i-1][j]>=s[i].t){
                f[i][j]=max(f[i][j],f[i-1][j]+s[i].f);//预处理f数组,如果f[i-1][j]的血量>=i个垃圾,那么可以转移,表示不用垃圾增加高度但是用它加血 
              }
              if(j>=s[i].h&&f[i-1][j-s[i].h]>=s[i].t){
                  f[i][j]=max(f[i][j],f[i-1][j-s[i].h]);//如果j大于垃圾高度,并且血量满足要求,那么f[i][j]可以转移,表示用垃圾增加高度,不加血 
              }
            }
        }
        int res1=10;
        int resh=0;
        for(i=1;i<=m;i++){
            for(j=0;j<=n;j++){
                if(f[i][j]>=s[i].t){
                    resh=max(resh,j);
                }
                res1=max(res1,f[i][j]);//计算最大血量 
            }
            if(resh==n)//高度满足要求就退出 
            break;
        }
        if(resh==n)
        cout<<s[i].t<<endl;
        else
        cout<<res1<<endl;
        
    }
    View Code
  • 相关阅读:
    js使用sessionStorage、cookie保存token
    在vue项目中的main.js中直接使用element-ui中的Message 消息提示、MessageBox 弹框、Notification 通知
    git报错:'fatal:remote origin already exists'怎么处理、附上git常用操作以及说明
    Module build failed: TypeError: loaderContext.getResolve is not a function
    Git相关命令
    用户反馈录
    静雅斋数学[目录]
    探索|尝试编制高质量的跟踪训练试卷
    直线参数方程何时必须化为标准形式
    快速高效的做三角函数图像
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12029014.html
Copyright © 2011-2022 走看看