zoukankan      html  css  js  c++  java
  • Codevs1684 垃圾陷阱

    题目链接

    Usaco 垃圾陷阱

    题目描述 Description

    卡门——农夫约翰极其珍视的一条Holsteins奶牛——已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D (2 <= D <= 100)英尺。
    
    卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。
    
    每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。
    
    假设卡门预先知道了每个垃圾扔下的时间t,以及每个垃圾堆放的高度h和吃进该垃圾能维持生命的时间f,要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续10小时的能量,如果卡门10小时内没有进食,卡门就将饿死。
    

    输入描述 Input Description

    第一行为2个整数,D 和 G ,G为被投入井的垃圾的数量。

    第二到第G+1行每行包括3个整数:T,表示垃圾被投进井中的时间;F,表示该垃圾能维持卡门生命的时间;和 H (1 <=H<=25),该垃圾能垫高的高度。

    输出描述 Output Description

    如果卡门可以爬出陷阱,输出一个整表示最早什么时候可以爬出;否则输出卡门最长可以存活多长时间。

    样例输入 Sample Input

    20 4

    5 4 9

    9 3 2

    12 6 10

    13 1 1

    样例输出 Sample Output

    13

    数据范围及提示 Data Size & Hint

    [样例说明]

    卡门堆放她收到的第一个垃圾:height=9;

    卡门吃掉她收到的第二个垃圾,使她的生命从10小时延伸到13小时;

    卡门堆放第3个垃圾,height=19;

    卡门堆放第4个垃圾,height=20。

    乍一看这道题,没有任何思路...不过数据范围非常小,于是我们就可以暴力的搞一搞Dp
    这其实是一道二维的背包,dp[i][j]表示到第i秒,搭起的高度为j时,所剩余的生命值
    但是,我们可以发现,每次一拿到垃圾就进行操作,才能保证决策最优,于是第一维可以优化成dp[i][j]表示投下第i个垃圾后,搭成的高度为j时的剩余生命。
    这样也避免了有两个垃圾同时投下的细节处理
    设f[i]为续命值,h[i]为高度,d[i]为投下的时间,转移显然:

    $$ int pass=t[i]-t[i-1] $$

    $$ dp[i][j]=max(dp[i][j],dp[i-1][j-h[i]]-pass); $$

    $$ dp[i][j]=max(dp[i][j],dp[i-1][j]+f[i]-pass); $$

    代码就是

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=105;
    int dp[maxn][20010];
    struct node{
    	int t,f,h;
    	bool operator <(const node& rhs)
    		const{
    			return t<rhs.t;
    		}
    }a[maxn];
    
    int read(){
    	int Value=0,Base=1;char Ch=getchar();
    	for(;!isdigit(Ch);Ch=getchar())if(Ch=='-')Base=-1;
    	for(;isdigit(Ch);Ch=getchar())Value=Value*10+(Ch^'0');
    	return Value*Base;
    }
    /* dp[i][j] i th and j heighth*/
    int main( ){
    	int m,n,j,k,i,hh=-1e9;
    	k=read();n=read();
    	for(i=1;i<=n;i++)
    		a[i].t=read(),a[i].f=read(),a[i].h=read();
    	sort(a+1,a+n+1);
    	memset(dp,-31,sizeof dp);
    	dp[0][0]=10;
    	a[0].t=0;
    	int ans=-1e9;int imax=1e9;
    	for(i=1;i<=n;i++){
    		for(j=0;j<=n+maxn;j++){
    			int pass=a[i].t-a[i-1].t;
    			if(dp[i-1][j-a[i].h]-pass>=0 && j-a[i].h>=0)
    				dp[i][j]=max(dp[i][j],dp[i-1][j-a[i].h]-pass);
    			if(dp[i-1][j]-pass>=0)
    				dp[i][j]=max(dp[i][j],dp[i-1][j]+a[i].f-pass);
    			ans=max(ans,a[i].t+dp[i][j]);
    			if(dp[i][j]>=0 && j>=k)imax=min(imax,a[i].t);
    		}
    	}
    	if(imax!=1e9)printf("%d
    ",imax);
    	else printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    LeetCode(111) Minimum Depth of Binary Tree
    LeetCode(108) Convert Sorted Array to Binary Search Tree
    LeetCode(106) Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode(105) Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode(99) Recover Binary Search Tree
    【Android】通过经纬度查询城市信息
    【Android】自定义View
    【OpenStack Cinder】Cinder安装时遇到的一些坑
    【积淀】半夜突然有点想法
    【Android】 HttpClient 发送REST请求
  • 原文地址:https://www.cnblogs.com/ABCDXYZnoip/p/7672889.html
Copyright © 2011-2022 走看看