首页 > 其他分享 >填表法与刷表法

填表法与刷表法

时间:2022-10-27 21:23:48浏览次数:60  
标签:10 le int 卡门 填表 刷表法 垃圾

填表法

填表法及\(f[i]\)由\(f[i-1]\)等类似的已经更新过的状态转移过来一般比较习惯用填表法(比较好想)

刷表法

刷表法及用\(f[i]\)去更新\(f[i+1]\)等之后未更新完全的状态(后面的状态可能会被之前的多个状态更新)
虽然用的少但是在一些题上用刷表法会比填表法要更加方便

填表法eg:

状态比较好想将几个需要的状态列出来
\(i:\)选到了哪个物品(提前排好序当满足条件时当前物品的时间既是答案)
\(h:\)当前到达的高度
\(hp:\)当前所有能活到的时间
设状态:\(f[i][j]\)为选到第\(i\)个物品到达\(j\)的高度所能到达的最大hp
此题若用填表法边界情况处理起来很麻烦
尤其是在高度的那一维
因为如果高度超过\(D\)也可以出井而高度的上限就很难处理
而用刷表法当可以到达某一高度且高度大于\(D\)直接输出然后\(return\) \(0\)即可
如果到不了\(D\)前面则不会\(return\) \(0\)就直接把扔下来的垃圾全吃掉直到挺不到下一个垃圾的到来(好凄惨)

P1156 垃圾陷阱

题目描述

卡门――农夫约翰极其珍视的一条 Holsteins 奶牛――已经落了到 “垃圾井” 中。“垃圾井” 是农夫们扔垃圾的地方,它的深度为 \(D\)(\(2 \le D \le 100\))英尺。

卡门想把垃圾堆起来,等到堆得高度大等于于井的深度时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。

每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。

假设卡门预先知道了每个垃圾扔下的时间 \(t\)(\(1 \le t \le 1000\)),以及每个垃圾堆放的高度 \(h\)(\(1 \le h \le 25\))和吃进该垃圾能维持生命的时间 \(f\)(\(1 \le f \le 30\)),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续 \(10\) 小时的能量,如果卡门 \(10\) 小时内(不含 \(10\) 小时,维持生命的时间同)没有进食,卡门就将饿死。

输入格式

第一行为两个整数,\(D\) 和 \(G\)(\(1 \le G \le 100\)),\(G\)为被投入井的垃圾的数量。

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

输出格式

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

样例 #1

样例输入 #1

20 4
5 4 9
9 3 2
12 6 10
13 1 1

样例输出 #1

13

提示

【样例说明】

卡门堆放她收到的第一个垃圾:\(\mathrm{height}=9\);

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

卡门堆放第 \(3\) 个垃圾,\(\mathrm{height}=19\);

卡门堆放第 \(4\) 个垃圾,\(\mathrm{height}=20\)。

std:

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n,m;
struct A
{
	int t,g,h;
}a[N];
bool cmp(A x,A y){return x.t < y.t;}
int f[N][110]; 
int sumh;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= m;i++)scanf("%d%d%d",&a[i].t,&a[i].g,&a[i].h);
	sort(a+1,a+1+m,cmp);
	f[0][0] = 10;
	for(int i = 0;i < m;i++)
		for(int j = 0;j <= n;j++)
		{
			if(a[i+1].t <= f[i][j])//hp必须能够挺到$i+1$个垃圾扔下来
			{
				if(j+a[i+1].h >= n)return printf("%d",a[i+1].t),0;
				f[i+1][j+a[i+1].h] = max(f[i+1][j+a[i+1].h],f[i][j]);
				f[i+1][j] = max(f[i+1][j],f[i][j]+a[i+1].g);
			}	
		}
	int sum = 10;//初始值为10
	for(int i = 1;i <= m;i++)
	{
		if(sum < a[i].t)break;
		sum += a[i].g;
	}
	
	printf("%d",sum);
	return 0;
}

标签:10,le,int,卡门,填表,刷表法,垃圾
From: https://www.cnblogs.com/AC7-/p/16833768.html

相关文章