题解 密室逃脱
好题,但还没细想就开始讲题就是在浪费题
操作是可逆的
设 \(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;
}