#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
int* tone = new int[n + 1];
for(int i = 0; i <= n; i++){
cin>>tone[i];
}
int* path = new int[n + 1];
if(n == 1) {
cout<<1<<endl;
cout<<0<<' '<<endl;
}
else if(n == 2){
cout<<1<<endl;
cout<<0<<' '<<endl;
}
else{
int demo;
path[n - 2] = n + 1;
path[n - 1] = n + 1;
path[n] = n + 1;
for(int i =n - 3; i >= 0; i--){
demo = tone[i + 3]; path[i] = i + 3;
if(tone[i + 2] <= tone[ i + 3]){
demo = tone[i + 2];path[i] = i + 2;
}
if(tone[i + 1] <= demo){
demo = tone[i + 1];path[i] = i + 1;
}
tone[i] += demo;
}
cout<<tone[0]<<endl;
cout<<0;
for(int i = path[0]; i <= n; i = path[i]){
cout<<' '<<i;
}
cout<<endl;
}
return 0;
}
因为最近学的动态规划,所以很自然的想到用dp解决,但是,习惯促使自己从前往后跳,以至于在找字典序最小的路径的时候卡壳了。
因为题目要求的是踩过的总石头数最小,所以从前往后和从后往前本质上是一样的,并且,从后往前方便求出最小的字典序。
学了俩周的dp 感觉自己一般的动态规划应该很容易解决的 ,但是每次做题还是会卡脖子
刚开始的时候想不到怎么从后面往前面跳
dp不仅要求出结果,记录结果的过程也很重要