【难】动态规划 多多看DVD(加强版)——二维背包问题(及背包问题通解整理)

题目大意:N个碟片中选M个,总时间不能超过L,求最大价值  题目

有好几个不大明白的地方:

1、一开始用三维,总是只能拿10、20分,我估计原因是从i到i+1个物品的传递没有做好。(以后碰到二维背包就用倒序降维方法做吧,避免出错)

2、初始化dp[j][1]会出错。后来想到dp[j][1]是存储了上一个维度的值,不可以初始化。(除非三维)

背包问题整理如下:

一维01背包问题通解:
for i=1..N
  for v=V..0
  {
    f[v]=max{f[v],f[v-c[i]]+w[i]};
    if (f[v]==f[v-c[i]]+w[i]) g[i,v]=1;//若f[v]选择后一项(输出用)
  }
01背包问题输出:
i=N
v=V
while(i>0)
{
  if(g[i][v]==0)
      print "未选第i项物品"
  else if(g[i][v]==1)
      print "选了第i项物品"
  v=v-c[i]
}
01背包求方案总数
    初始化:f[0][0]=1;
    f[i][v]+=f[i-1][v-c[i]];

01背包求最优方案总数:
for i=1..N
for v=0..V
{
  f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
  g[i][v]=0
  if(f[i][v]==f[i-1][v])
  g[i][v]+=g[i-1][v];
  if(f[i][v]==f[i-1][v-c[i]]+w[i])
  g[i][v]+=g[i-1][v-c[i]];
}
一维完全背包问题通解:
for i=1..N 
for v=0..V 
f[v]=max{f[v],f[v-c[i]]+w[i]};
分组背包问题(k个组,每组要么取一个要么不取)
for k=1...K
        for v=V...0
            for item in group k
                    f[v]=max{f[v],f[v-c[i]]+w[i]};

本题ac代码:

#include
#include
using namespace std;
int c[101],w[101],dp[1001][101];
int main()
{
	int N,M,L,i,j,k,ans=0;
	cin>>N;cin>>M;cin>>L;
	for (i=1;i<=N;i++)
		cin>>c[i]>>w[i];
	memset(dp,-1,sizeof(dp));
	dp[0][0]=0;
	for (i=1;i<=N;i++)
		for (j=L;j>=c[i];j--)
		{
		//	dp[j][1]=w[i];//删了这个就对了
			for (k=1;k<=i;k++)
				if (dp[j-c[i]][k-1]!=-1 )
					dp[j][k]=max(dp[j][k],dp[j-c[i]][k-1]+w[i]);
			ans=max(ans,dp[j][M]);
		}
	cout<

 

你可能感兴趣的:(dp)