题解 密室逃脱

传送门

好题,但还没细想就开始讲题就是在浪费题

操作是可逆的
\(f_{i, j}\) 表示能到达第 i 个房间的人数恰好为 j 时,前 i 个房间最多有多少人
转移分类讨论

因为几乎没有任何地方是自己想的所以题解就水了
如果某天再来看这个题的话记得去膜拜yspm的题解

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m;
int f[1010][20010];
const int lim=20000;
int a[N], b[N], ans=-INF;

signed main()
{
	freopen("escape.in", "r", stdin);
	freopen("escape.out", "w", stdout);
	
	n=read(); m=read();
	for (int i=1; i<n; ++i) a[i]=read(), b[i]=read();
	for (int i=1; i<m; ++i) f[1][i]=i;
	for (int i=1; i<n; ++i) {
		int mx=-INF;
		for (int j=0; j<a[i]; ++j) mx=max(mx, f[i][j]);
		for (int j=0; j<a[i]; ++j) f[i+1][j+b[i]]=max(f[i+1][j+b[i]], f[i][j]+b[i]);
		for (int j=0; j<b[i]; ++j) f[i+1][j]=max(f[i+1][j], mx+j);
		for (int j=a[i]; j<a[i]+b[i]; ++j) f[i+1][j-a[i]]=max(f[i+1][j-a[i]], f[i][j]);
		for (int j=a[i]+b[i]; j<=lim; ++j) f[i+1][j]=max(f[i+1][j], f[i][j]);
	}
	for (int i=0; i<=lim; ++i) ans=max(ans, f[n][i]);
	cout<<ans<<endl;

	return 0;
}
posted @ 2022-03-26 20:45  Administrator-09  阅读(2)  评论(0编辑  收藏  举报