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

论坛 期权论坛 脚本     
匿名技术用户   2020-12-27 00:22   11   0

题目大意: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<iostream>
#include<string.h>
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<<ans;
 return 0;
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP