1.滚动数组
观察二维表dp[][]可发现,每一行都是由上一行推出,且只与上一行有关,与更前面的行无关,因此用新的一行覆盖原来的即可。
2.使用滚动数组的必要性
动态规划的题经常会给出很大的N和V,经过滚动数组的优化,空间复杂度从O(NV)减少为O(V),
普通二维可能会导致TEl。
但滚动数组也有缺点,它覆盖了中间转移状态,只留下了最后的状态,导致无法输出背包方案。
3.代码
#include<iostream>
#include<algorithm>
using namespace std;
int n,T;
int dp[1010];
struct note
{
int t;
int m;
}a[110];
int main()
{
int i,j;
int tot;
cin>>T>>n;
for (i=1;i<=n;i++)
cin>>a[i].t>>a[i].m;
for (i=1;i<=n;i++)
for (j=T;j>=a[i].t;j--)
dp[j]=max(dp[j],dp[j-a[i].t]+a[i].m);
cout<<dp[T];
return 0;
}
#代码分析:
第二层循环必须逆序,即从后往前覆盖。目的是为了避免重复。
少掉的一层是i行,留下的是j列。