一、滚动数组
滚动数组是在动态规划里面的一种降低空间复杂度的办法,它的形式是将二维数组转换为一维数组,在一题目当中,还可以减少时间复杂度
而如果要运用这种办法,就需要观察动态方程,将一些用过的数据弃掉,也就说将新的数据覆盖掉旧的数据
我们以01背包为例
我们知道dp[i][j]代表最大价值(最小价值,在这里用最大价值为例),i表示第几种物品,j表示放下的体积
那么有俩种方法,一种是不拿这个物品,一种是拿这个物品
拿:dp[i][j]=dp[i-1][j-wight[i]]+value[i];
不拿:dp[i][j]=dp[i-1][j]
那么最大价值为dp[i][j]=max(dp[i-1][j],dp[i-1][j-wight[i]]+value[i])
那么不用滚动数组实现为
#include<stdio.h>
int n,v,dp[100][100];
int a[100];//每个物品占用空间
int b[100];//每个物品的价值
int main()
{
int i,j;
scanf("%d %d",&n,&v);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
scanf("%d",&b[i]);
for(i=1;i<=n;i++)//第i个物品
for(j=v;j>=0;j--)//剩余空间j
{
if(j >= a[i])//如果装得下
dp[i][j]=max( dp[i-1][j-a[i]]+b[i],dp[i-1][j]);
else//如果装不下
dp[i][j]=dp[i-1][j];
}
printf("%d",dp[n][v]);//输出答案
}
如果用滚动数组
#include<stdio.h>
int n,v,dp[100];
int a[100];
int b[100];
int main()
{
int i,j;
scanf("%d %d",&n,&v);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
scanf("%d",&b[i]);
for(i=1;i<=n;i++)
for(j=v;j>=a[i];j--)
{
dp[j]=max(dp[j-a[i]]+b[i],dp[j]);
}
printf("%d",dp[v]);
}
由此我们可以看出,我们当要求出新数据时,我们只需要用到i-1行的数据,而i-2,i-3行的数据,我们就不需要了,因此我们要用滚动数组的时候就需要注意这个问题