题解:P6715 [CCO 2018] Fun Palace
模拟赛被卡常了。
赛时认为记忆化搜索非常自然,我们考虑搜索第
临界条件肯定是
首先若
if(a[now]>=maxm)ans=max(maxm-1+dfs(now+1,b[now]),dfs(now+1,b[now]+maxm));
其次就是
else ans=max(max(a[now]-1+dfs(now+1,b[now]),a[now]+dfs(now+1,min(b[now],maxm-a[now]))),dfs(now+1,max(maxm,b[now]+a[now])));
code
#include<bits/stdc++.h>
#define N 2020
#define M 40020
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<= '9')x=x*10+(ch-'0'),ch=getchar();
return x*f;
}
int n,m,Mnow;
int a[N],b[N];
int f[N][M];
int dfs(int now,int maxm){
if(f[now][maxm])return f[now][maxm];
int ans=0;
if(now==n){return f[now][maxm]=maxm-1;}
if(a[now]>=maxm)ans=max(maxm-1+dfs(now+1,b[now]),dfs(now+1,b[now]+maxm));
else ans=max(max(a[now]-1+dfs(now+1,b[now]),a[now]+dfs(now+1,min(b[now],maxm-a[now]))),dfs(now+1,max(maxm,b[now]+a[now])));
return f[now][maxm]=ans;
}
int main(){
n=read();m=Mnow=read();
for(int i=1;i<n;i++)
a[i]=read(),b[i]=read(),Mnow=max(Mnow,max(a[i],b[i]));
printf("%d\n",dfs(1,m));
return 0;
}