求解一个多维背包问题

rd_qa 2012-08-22 04:15:52
如下一个二维背包问题:
TOJ3596,题意很简单,有N张光盘,每张光盘有一个价钱,现在要从N张光盘中买M张,预算为L,每张光盘有一个快乐值,要求在不超过预算并且恰好买M张,使得快乐值最大。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define INF 0x1f1f1f1f
using namespace std;
int dp[105][1005],cost[105],value[105];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int i,j,k,n,m,T,L;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&L);
for(i = 1;i <= n; ++i)
scanf("%d%d",&cost[i],&value[i]);
for(i = 1;i <= m; ++i)
for(j = 0;j <= L; ++j){
dp[i][j] = -INF;
dp[0][j] = 0;
}
for(k = 1;k <= n; ++k)
for(j = m;j >= 1; j--)
for(i = L;i >= cost[k]; --i){
dp[j][i] = max(dp[j][i],dp[j-1][i-cost[k]]+value[k]);
}
int ans = 0;
for(i = 1;i <= L; ++i)
if(dp[m][i] > ans)
ans = dp[m][i];
printf("%d/n",ans);
}
}

*************************
我想知道的是,如何求解选中的到底是那几张光盘?

先谢谢大家,呵呵。
...全文
615 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
rd_qa 2012-08-28
  • 打赏
  • 举报
回复
《背包问题九讲》我看过了的,就看了前面几节,没有看到输出方案哪里,
呵呵,读书不认真。

总之感谢呀,感谢。
rd_qa 2012-08-23
  • 打赏
  • 举报
回复
非常感谢,用这个算法可以搞定了,
但是需要提醒注意的是,如果i是从0开始的,条件if g[i][v][_v]==0可能会漏选第一个物体。
所以我把g[][][]初始值设置为-1了。

i=N,v=L1,_v=L2(N是物品总数,v,_v是两个限制条件).
while i>0
do if g[i][v][_v]==0
then output 未选第i件物品
else output 选了第i件物品,v<-v-r1[i],_v<-_v-r2[i].(r1,r2为i的两个代价).
i<-i-1.

请问Only_phantasy,有什么书籍可以全面的学习这些知识么?
还是都是你自己思考的结果?
I'm Daniel Du 2012-08-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

非常感谢,用这个算法可以搞定了,
但是需要提醒注意的是,如果i是从0开始的,条件if g[i][v][_v]==0可能会漏选第一个物体。
所以我把g[][][]初始值设置为-1了。

i=N,v=L1,_v=L2(N是物品总数,v,_v是两个限制条件).
while i>0
do if g[i][v][_v]==0
then output 未选第i件物品
else out……
[/Quote]
你既然会写状态转移方程?怎么能不会输出方案?
这里给出的方法就是输出方案的基本方法啊.
I'm Daniel Du 2012-08-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

非常感谢,用这个算法可以搞定了,
但是需要提醒注意的是,如果i是从0开始的,条件if g[i][v][_v]==0可能会漏选第一个物体。
所以我把g[][][]初始值设置为-1了。

i=N,v=L1,_v=L2(N是物品总数,v,_v是两个限制条件).
while i>0
do if g[i][v][_v]==0
then output 未选第i件物品
else out……
[/Quote]
这是前人思考的结果.他的名字是崔天翼,写的<背包九讲>,我记得背包九讲写过,就匆忙的看了下,有错误还请谅解了:)
背包方面的资料还有很多,像国家集训队论文,国家集训队作业中就有一些高手讨论过.由于背包问题是NP完全问题,这方面的国际论文也不少,由于太过学术化,我就不详细列举了.
I'm Daniel Du 2012-08-22
  • 打赏
  • 举报
回复
用g[i][v]表示递推项f[i][v]时使用了f[i-1][v]还是f[i-1][v-weight[i]].
i=N,v=V.(N是物品总数,v是当前背包容量).
while i>0
do if g[i][v]==0
then output 未选第i件物品
else output 选了第i件物品,v<-v-weight[i].
i<-i-1.

这是一维背包的方案输出.

如果是二维的话,
i=N,v=L1,_v=L2(N是物品总数,v,_v是两个限制条件).
while i>0
do if g[i][v][_v]==0
then output 未选第i件物品
else output 选了第i件物品,v<-v-r1[i],_v<-_v-r2[i].(r1,r2为i的两个代价).
i<-i-1.

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧