牛客月赛49 E题 禅(DP)

题目链接

 

题目描述

骑士?只是我手上的傀儡而已,冲锋!

本题请格外注意标红和加粗的字!

你是一个骑士,现有一个包含 NNN 个格子的一维棋盘(一行 NNN 列)。


第 iii 个格子有一个战斗力为 aia_iai​ 的怪物:所有怪物对应的 ai>0a_i>0ai​>0,若 ai=0a_i=0ai​=0 表示第 iii 列是公主。

你的任务目标是营救被困于该格的公主(走到公主所在的格子),你需要选择一个 公主不在 的格子作为起点,任意时刻 重复 经过已经走过的点。

到达某个格子时,必须与当前怪物战斗,如果战斗力严格大于其战斗力,可以击败它并获得它所具有的全部战斗力。

形式化地,设你的战斗力是 mmm,怪物的战斗力是 aia_iai​:

战斗{m≤ai→任务失败m>ai→击败该怪物,且 m←m+ai\text{战斗}\begin{cases}m\le a_i\rightarrow\text{任务失败}\\m> a_i\rightarrow\text{击败该怪物,且}~m\leftarrow m+a_i\end{cases}战斗{m≤ai​→任务失败m>ai​→击败该怪物,且 m←m+ai​​

给定序列 {an}\{a_n\}{an​},求采用最优策略选择起点及行动路径时 最少 的初始战斗力 m0m_0m0​ 使得能完成任务目标。

输入描述:

全文第一行输入一个正整数 T(1≤T≤105)T(1\le T\le10^5)T(1≤T≤105),表示数据组数。

对于每组数据,第一行输入一个正整数 n(1≤n≤105,∑n≤3×106)n(\color{red}1\le\color{black}n\le10^5,\sum n\le3\times10^6)n(1≤n≤105,∑n≤3×106)。

第二行输入 nnn 个整数,第 iii 个表示 ai(0≤ai≤109)a_i(\color{red}0\le \color{black}a_i\le10^9)ai​(0≤ai​≤109)。

数据保证存在且仅存在一个 iii 满足 ai=0a_i=0ai​=0

输出描述:

对于每组数据,输出一行一个整数表示 m0m_0m0​ 的最小值,无解时输出一行字符串 No Solution\tt No~SolutionNo Solution

示例1

输入

复制2 5 1 2 3 4 0 5 4 4 4 4 0

2
5
1 2 3 4 0
5
4 4 4 4 0

输出

复制2 5

2
5

说明

所有的样例均从第一个格子开始遍历,一路向右即可。

 

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll dp[100010],a[100010];
int main()
{
	int t;cin>>t;
	while(t--)
	{
		int n;cin>>n;
		int pos=0;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			if(!a[i]) pos=i;找出公主所在的位置;
			}
		if(n==1) {
            cout<<"No Solution"<<endl;	//当只有一个位置的时候,这个位置是公主,没有骑士能够站的地方;
            continue;
        }
		for(int i=0;i<=n+5;i++)
			dp[i]=1e18;
		for(int i=pos+1;i<=n;i++)//从公主后面开始dp;
		{
			dp[i]=a[i]+1;
			if(i!=pos+1) dp[i]=max(dp[i],dp[i-1]-a[i]);
		}
		for(int i=pos-1;i>=1;i--)//从公主前面开始dp;
		{
			dp[i]=a[i]+1;
			if(i!=pos-1) dp[i]=max(dp[i],dp[i+1]-a[i]);
		}
		ll ans=1e18;
		for(int i=1;i<=n;i++)
			ans=min(ans,dp[i]);//找出最小的结果值
		cout<<ans<<endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值