二维费用背包问题:
对于每件物品,具有两种不同的费用;选择
这件物品必须同时付出这两种代价;
对于每种代价都有一个可付出的最
大值(背包容量)
。问怎样选择物品可以得到最大的价值。设这两种代
价分别为代价
1
和代价
2
,第
i
件物品所需的两种代价分别为
a[i]
和
b[i]
。两种代价可付出的最大值(两种背包容量)分别为
V
和
U
。物品
的价值为
w[i]
对于每件物品,具有两种不同的费用,必须支付这两种费用才能购买到这件物品,对于每种代价都有一个可支付的最大值(背包容量),求怎样选择物品才能使背包里物品的价值最大,设为代价1、代价2,第i件物品所需的代价为a[i],b[i],这两种代价的最大值分别为U、V,物品价值w[i]。设f[i][u][v]表示前i件物品付出代价u、v时的最大价值,状态转移方程:
f[i][u][v]=max(f[i-1][u][v],f[i-1][u-a[i]][v-b[i]]+w[i]);
若用前面(01、完全、多重)的优化方法把它优化:当物品只可以取一次时,u、v采用逆序循环,如完全背包时采用顺序,如多重背包时拆分物品。
(f[v][m]表示付出费用v,最多可选m物品的最大价值)
http://acm.hdu.edu.cn/showproblem.php?pid=2159
10 10 1 10 1 1 10 10 1 9 1 1 9 10 2 10 1 1 2 2
0 -1 1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int max(int a,int b)
{
return a>b?a:b;
}
//这个题目中消耗的忍耐度和最多杀的怪兽的个数就相当于2种付费
int n,m,k,s;
int p[105],w[105],dp[105][105];
int main()
{
int i,j;
while(~scanf("%d%d%d%d",&n,&m,&k,&s))
{
for(i=0;i<k;i++)
{
scanf("%d%d",&p[i],&w[i]);
}
memset(dp,0,sizeof(dp));
for(i=0;i<k;i++)
{
for(j=w[i];j<=m;j++)
{
for(int r=1;r<=s;r++)
{
dp[j][r]=max(dp[j][r],dp[j-w[i]][r-1]+p[i]);
}//dp[j][r]表示杀死r只怪兽消耗j忍耐度得到的最大的经验值
}
}
for(i=0;i<=m;i++)
{
if(dp[i][s]>=n)
{
printf("%d\n",m-i);
break;
}
}
if(i>m)
printf("-1\n");
}
return 0;
}
杭电 2159 FATE(二维费用背包问题),布布扣,bubuko.com
原文地址:http://blog.csdn.net/u012766950/article/details/38437247