青蛙1
题目描述
有N块宝石,编号为1,2,…,N。对于每个i(1≤i≤N),石头i的高度为hi。
最初有一只青蛙在Stone 1上。他将重复几次以下动作才能到达Stone N:
如果青蛙当前在Stone i上,则跳到Stone i + 1或Stone i + 2。这里,| hi-hj |的成本 发生,其中j是要落在上面的石头。
找到青蛙到达Stone N之前可能发生的最小总成本 。
约束
输入中的所有值都是整数。
2≤N≤10^5
1≤hi≤10^4
输入
输入来自标准输入,格式如下:
N
h1 h2…hN
输出
打印可能的最低总成本。
样例输入
【样例1】
4
10 30 40 20
【样例2】
2
10 10
【样例3】
6
30 10 60 10 60 50
样例输出
【样例1】
30
【样例2】
0
【样例3】
40
提示
样例1解释:如果我们沿着路径1→2→4,则产生的总成本为| 10−30 | + | 30−20 | = 30。
样例2解释:如果我们沿着路径1→2,样例总成本为| 10−10 | = 0。
样例3:如果按照路径1→3→5→6进行计算,则总成本为| 30−60 | + | 60−60 | + | 60−50 | = 40。
分析: s[i]表示到达Stone i的最小成本,所以s[n]最小只能是s[n-1]+abs(a[n]-a[n-1])和s[n-2]+abs(a[n]-a[n-2])中的一个,以此类推只要求出s[i-1]和s[i-2]就能求出s[i]。(注意初始化a[0]=a[1],不然a[2]-a[0]会出错)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100010],s[100010],n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
a[0]=a[1];
for(int i=2;i<=n;i++)
{
s[i]=min(s[i-1]+abs(a[i]-a[i-1]),s[i-2]+abs(a[i]-a[i-2]));
}
cout<<s[n]<<endl;
return 0;
}
青蛙2
题目描述
有N块宝石,编号为1,2,…,N。对于每个i(1≤i≤N),石头i的高度为hi。
最初有一只青蛙在石头1上。他将重复几次此动作才能到达石头N:
如果青蛙当前在石头i上,则跳至以下之一:石头
i + 1,i + 2 ,…,i + K。这里,| hi-hj |的成本 发生,其中j是要落在上面的石头。
找到青蛙到达Stone N之前可能发生的最小总成本 。
约束
输入中的所有值都是整数。
2≤N≤10^5
1≤K≤100
1≤hi≤10^4
输入
输入来自标准输入,格式如下:
NK
h1 h2…hN
输出
打印可能的最低总成本。
样例输入
【样例1】
5 3
10 30 40 50 20
【样例2】
3 1
10 20 10
【样例3】
2 100
10 10
【样例4】
10 4
40 10 20 70 80 10 20 70 80 60
样例输出
【样例1】
30
【样例2】
20
【样例3】
0
【样例4】
40
提示
样例1解释:如果我们沿着路径1→2→5,则总费用为| 10−30 | + | 30−20 | = 30。
样例2解释:如果我们沿着路径1→2→ 3,发生的总成本为| 10-20 | + | 20−10 | = 20。
样例3解释:如果按照路径1→2,则发生的总成本为| 10-10 | = 0。
样例4解释:如果我们沿着路径1→4→8→10,则总费用为| 40-70 | + | 70-70 | + | 70-60 | = 40。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100010],s[100010],n,k,kk;
int main()
{
cin>>n>>k;
for(int i=1; i<=n; i++)
{
cin>>a[i];
}
a[0]=a[1];
for(int i=2; i<=n; i++)
{
s[i]=s[i-1]+abs(a[i]-a[i-1]);
if(i<k) kk=i;
else kk=k;
for(int j=2;j<=kk;j++)
{
int x=abs(a[i]-a[i-j]);
s[i]=min(s[i],s[i-j]+x);
}
}
cout<<s[n]<<endl;
return 0;
}