1.动态规划的条件:
所谓动态规划就是把一个问题,划分成每一个小问题,从第一个小问题不断推进到后面的子问题;每一个阶段可以分为这样的想法:
每个阶段包括2种东西,一个是决策,就是当前这个阶段要怎么做,宁一个叫做状态,就是用一个标志表示当前状态
2.
一维数组的动态规划;
a.最长单调子序列:
输入一串数组输出单调递增的最大子序列:
比如
输入132 4 56
子序列1 2 4 5 6最大输出的应该是 5;
思路:
定义dp[i]表示a数组里面最长单调的长度;
每次要判断一下这个尾巴是否大于前面的一个,如果比前面一个大就加上一;
b.题目:洛谷
思路:
这样的题目我们这样想,用dp[i]表示当前感染了多少人;
我们考虑最后一轮,最后一次论感染的人就是上一轮的人数加上新感染的人,得出递推公式;
*dp【i】=dp[i-1]x+dp[i-1];
/*
1.dp[i]表示感染了i个人;
2.dp[i]=dp[i-1]+x*dp[i-1];
3.dp[0]=1
*/
#include <iostream>
using namespace std;
long long dp[10010];
int main()
{
int x,n;
cin>>x>>n;
dp[0]=1;
for(int i=1;i<=n;++i)
{
dp[i]=x*dp[i-1]+dp[i-1];
}
cout<<dp[n]<<endl;
}
跳马问题:
题目
思路:
我们用dp[i][j]表示当前的数组走到方法数;
dp[i][j]就是左边过来的方法 左边过来可以是i-2,j-1
i-2,j+1;
i-1,j+2;
i-1,j-2;
dp[i][j]=dp[i-2][j-1]+dp[i-2][j+1]+dp[i-1][j+2]+dp[i-1][j-2];
动态规划要注意初始化;
dp[0][0]=1;
判断边缘条件;
在最上边如何都走不到n,因为不能横着走;
所以都为0;
下面要转移,所以要保证数组不会越界,需要判断;
动态转移的时候要注意之前的状态已经被赋值的话才可以转移,不然后面更新不了,如果前面没有赋值的话;
既是
dp[i][j要计算的是i-2;
所以在计算i的时候i-2已经有值了,不用在计算;
所以循环是i从0到大的算;
注意循环顺序;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
if(i==0&&j!=0) dp[i][j]=0;//一开始在最上面的话因为不能走直线所以就为0;
else{
if(i>1){