zoukankan      html  css  js  c++  java
  • 洛谷P1156 Solution

    题目链接

    题解

    ⭐:试图达到或超过某目标值的dp可以考虑背包。

    将高度视作体积,吃掉所延长的生命时间视作价值,井高视作背包容量,此题即可转化为一个类背包问题。因为我们是依时间由小到大的顺序对垃圾进行决策的,因此所找到的第一个可以达到井高的垃圾,其时间一定为最短时间。

    状态:\(dp[i]\)表示当前垃圾高度为\(i\)时的最大生命时间。

    初始值:\(dp[0]=10\)

    转移方程:\(dp[j+h_i]=max(dp[j+h_i],dp[j]),\quad dp[j]+=f_i\quad (1\le i\le g,d\ge j\ge 0)\)

    第一种情况为用垃圾\(i\)垫高,第二种为吃掉。如果\(j\)正序循环会导致取\(dp[j]\)\(dp[j+h_i]\)在后面循环中又\(+f_i\),也就是我们既用\(j\)垫高又将其吃掉,因此需倒序循环(也可以不将数组滚动)。

    目标状态(如果无法出井):\(dp[0]\),因为不垫高并将能吃的都吃掉存活时间最长。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=110;
    struct node {int t,f,h;} a[N];
    int dp[N];
    bool cmp(node x,node y) {return x.t<y.t;}
    int main()
    {
    	int d,g;
    	scanf("%d%d",&d,&g);
    	for(int i=1;i<=g;i++) scanf("%d%d%d",&a[i].t,&a[i].f,&a[i].h);
    	sort(a+1,a+g+1,cmp); dp[0]=10;
    	for(int i=1;i<=g;i++)
    	{
    		for(int j=d;j>=0;j--)
    		{
    			if(dp[j]<a[i].t) continue;
    			if(j+a[i].h>=d) {printf("%d",a[i].t); return 0;}
    			dp[j+a[i].h]=max(dp[j+a[i].h],dp[j]);//垫高高
    			dp[j]+=a[i].f;//吃掉 
    		}
    	}
    	printf("%d",dp[0]);
    	return 0;
    }
    
  • 相关阅读:
    读取XML类
    服务器每隔一段时间执行一次任务
    关于购物网站的支付接口(.NET)
    CentOS学习
    CentOS6.4 V1.0
    jquery选择器 选择器性能问题
    css选择器总结
    遮罩层,可拖动
    第四次作业结对编程
    C++中常用类型的转换总结
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14540432.html
Copyright © 2011-2022 走看看