题目描述
骑士?只是我手上的傀儡而已,冲锋!
本题请格外注意标红和加粗的字!
你是一个骑士,现有一个包含 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;
}