A 马
A 马
状态 \(f[i][j][k]\) 表示骑 \(i\) 次大圈、\(j\) 次小圈、\(k\) 次过河至少需要的马数。
发现过河一定是最先进行的,每次考虑最后一匹马的转移,只要是对应的三元组执行完后不会累倒就行。
可行的三元组不多,而且 \(i,j,k=100,100,100\) 是最坏的情况,才 \(10^6\).
#include<iostream>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while
const int N=160,M=310,INF=1e9;
int n,m,f[M][M][M],A,B,C,ans;
#define z(x) (x>0?x:0)
int main(){
// #ifndef ONLINE_JUDGE
// freopen("1.in","r",stdin);
// #endif
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>A>>B>>C;
// cout<<n<<' '<<m<<' '<<A<<' '<<B<<' '<<C<<'\n';
L(i, A+1)
L(j, B+1)
L(k, C+1){
if(!i&&!j&&!k)continue;
f[i][j][k]=INF;
// printf("f[%d][%d][%d]=%d\n",i,j,k,f[i][j][k]);
for(int a=0;a<2;++a)
for(int b=0;b*20+a*50<100;++b)
for(int c=0;b*20+a*50+(1<<c)<=100;++c){
if(!a&&!b&&!c)continue;
f[i][j][k]=min(f[i][j][k],f[z(i-a)][z(j-b)][z(k-c)]+1);
}
if(f[i][j][k]<=n)ans=max(ans,i+j+k);
}
cout<<ans;
return 0;
}