洛谷 P1095 守望者的逃离(贪心,空间压缩DP)

23 篇文章 0 订阅

题目大意:

我们控制一个人,他的初始魔力值为M。每一秒他有三个动作,分别是:不耗魔继续往前跑17米,或者耗10点魔力使用闪烁往前60米,或者停止不动魔加4点。

现在给定时间T,问是否能走到S

已知M,S,T。其中M代表魔力值,S代表距离,T代表时间。

解题思路:

首先,我们可以容易看出,若初始有魔的话,最好让魔只剩m%=10,因为耗完所有闪烁次数是最合理的。

然后,我们看到若状态为

state=[time][mona],其中time代表还剩多少时间,mona为还剩多少魔力值,表示还剩time,mona时最远能走多少,那么我们可以得到

if mona<10

memo[time][mona]= max(memo[time-1][mona+4],memo[time-1][mona]+17)

else

memo[time][mona]= max(max(memo[time-1][mona+4],memo[time-1][mona]+17),memo[time-1][mona-10]+60)

其中边界条件为:

if mona>=10

memo[1][mona]=60

else

memo[1][mona]=17

但是,我们发现memo空间为1e8,超过了空间复杂度1e7,那么我们要进行空间压缩,我们发现每一个时刻的状态只和下一个时刻的状态有关,所以[time]这一栏可以变为[2],即

state=[2][mona]

#include <bits/stdc++.h>
using namespace std;
const int MAXM = 1020;
int memo[2][MAXM];

int main(){
	int m,s,t;
	cin>>m>>s>>t;
	int times=m/10;
	m=m%10;
	if(times<=t){
		if(times*60 >=s){
			cout<<"Yes"<<endl;
			double ans=ceil((double)s/60);
			cout<<(int)ans<<endl;
			exit(0);
		}
		else{
			s-=times*60;
			t-=times;
		}
	}else{
		if(t*60>=s){
			cout<<"Yes"<<endl;
			double ans=ceil((double)s/60);
			cout<<(int)ans<<endl;
			exit(0);
		}
		else{
			cout<<"No"<<endl;
			cout<<t*60<<endl;
			exit(0);
		}
	}
	
	int cur=1;
	
	memset(memo,0,sizeof(memo));
	
	for(int time=1;time<=t;time++){
		cur=!cur;
		for(int mona=0;mona<=m+20;mona++){
			if(time==1){
				if(mona>=10)
				memo[cur][mona]=60;
				else memo[cur][mona]=17;
				continue;
			}
			if(mona<10){
				memo[cur][mona]=max(memo[!cur][mona]+17,memo[!cur][mona+4]);
			}else{
				memo[cur][mona]=max(memo[!cur][mona]+17,memo[!cur][mona-10]+60);
				memo[cur][mona]=max(memo[cur][mona],memo[!cur][mona+4]);
			}
			}
		if(memo[cur][m]>=s){
			cout<<"Yes"<<endl;
			cout<<time+times<<endl;
			exit(0);
		}
	}
	
	
	cout<<"No"<<endl;
	cout<<memo[cur][m]+times*60<<endl;
	return 0;

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值