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;
}
posted @ 2023-11-17 12:56  wscqwq  阅读(2)  评论(0编辑  收藏  举报