ABC266D Snuke Panic (1D) 题解
- 洛谷题目传送门
- AtCoder 题目传送门
思路分析
考虑 dp。
设
因为每秒高桥只能移动一个位置,所以
代码实现
有几点要注意:
- 一开始高桥在
0 位置,所以在第1 时刻他到不了2,3,4 的位置,第2 时刻到不了3,4 的位置,以此类推。所以在dp 第二层循环的时候要注意限制一下循环的范围。 - 在最后一个 Snuke 出现之后,再跑来跑去已经没有意义了,所以
dp 第一层循环的范围应该是从1 到mxt ,其中mxt 为最后一个 Snuke 出现的时间。这个时间可以在输入时维护。 - 答案应为
\max\limits_{i=0}^4 dp_{mxt,i} ,其中mxt 为最后一个 Snuke 出现的时间。 - 找
x 可以用lower_bound找,因为每个时刻最多只会出现一只 Snuke(见数据范围),所以非常方便。 -
时间复杂度
#include<algorithm>
#include<cstdio>
#define int long long
using namespace std;
const int maxn=1e5+1;
int n,t[maxn],x[maxn],a[maxn],dp[maxn][5],mxt=0;
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;++i){
scanf("%lld%lld%lld",&t[i],&x[i],&a[i]);
mxt=max(t[i],mxt);//统计最后一个Snuke出现的时间。
}
for(int i=1;i<=mxt;++i){
for(int j=0;j<=min(i,4ll);++j){//限制循环范围。
dp[i][j]=dp[i-1][j];
if(j>0) dp[i][j]=max(dp[i-1][j-1],dp[i][j]);//dp,注意特判。
if(j<4) dp[i][j]=max(dp[i-1][j+1],dp[i][j]);
int pos=lower_bound(t+1,t+1+n,i)-t;//二分找x。
if(t[pos]==i&&x[pos]==j) dp[i][j]+=a[pos];
}
}
printf("%lld\n",max(max(max(max(dp[mxt][0],dp[mxt][1]),dp[mxt][2]),dp[mxt][3]),dp[mxt][4]));
return 0;
}
输入似乎是按照
因为“中文句子句末不加句号”的奇怪原因被打回了,现在加上了注释的句号。