好久没更新了,今天就来更一下吧!
先来说说题目:
小仓鼠带着货物,从中国送到安息,丝绸之路包括起点和终点一共有N+1个城市,0号城市是起点长安,N号城市是终点巴格达。要求不超过M天内必须到达终点。一天的时间可以从一个城市到连续的下一个城市。从i-1城市到i城市距离是Di。
大家都知道,连续赶路是很辛苦的,所以小仓鼠可以在一个城市时,可以有以下选择:
移动:向下一个城市进发
休息:呆在原来的城市不动
沙漠天气变化无常,在天气很不好时,前进会遇到很多困难。我们把M天的第j(1< j MCji-ijDiCjp>
不过小仓鼠还是有选择权的,可以避开比较恶劣的天气,休息是不会消耗疲劳值的。现在他想知道整个行程最少要消耗多少疲劳值。
估计资深OIer们很快就能知道这是一道动归题
然后再来普及一下动归的一大要素——状态转移方程.
然而这道题的状态转移方程显而易见,也就是比较当前的天气以及疲劳度来判断是走还是休息.
因此可以推出,走的疲劳度为dp[i-1][j-1]+d[i]*c[j],休息的疲劳度为dp[i][j-1].
所以状态转移方程为:
min(dp[i][j-1],dp[i-1][j-1]+d[i]*c[j]);//比较是走花费的体力多还是休息花费的体力多.
然后知道了状态转移方程,那么就简单了,首先我们知道需要定义两个数组,分别是D和C,变量n,m,然后还有动归的标配——动归数组dp
随后我们要读入n,m和D,C,然后就是被代码了~
随后就万事俱备只欠代码了!
因此,我就将C++20(啊呸!)代码附上啦:
#include<bits/stdc++.h>
using namespace std;
int d[10005],c[1005],dp[1005][1005];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>d[i];
for(int i=1;i<=m;i++)
cin>>c[i];
memset(dp,0x3f,sizeof(dp));
memset(dp[0],0,sizeof(dp[0]));
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
dp[i][j]=min(dp[i][j-1],dp[i-1][j-1]+d[i]*c[j]);
cout<<dp[n][m]<<endl;
return 0;
}