您的位置:首页 > 其它

51nod 1086 背包问题 V2(多重背包)

2016-10-02 18:39 369 查看
51nod 1086 背包问题 V2(多重背包)

多重背包每种有限定的数量,可以转化为01背包来做。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define E 2.71828
#define MOD 1000000007
#define N 110
int dp[50005];
int v
,w
,c
;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++)
scanf("%d%d%d",&v[i],&w[i],&c[i]);
for(int i = 1; i <= n; i++)
{
for(int k = 1; k <= c[i]; k++)
for(int j = m; j >= v[i]; j--)
dp[j] = max(dp[j],dp[j-v[i]]+w[i]);
}
printf("%d\n",dp[m]);
return 0;
}


时间优化:

但是,这题不像hdu 2191那样,数据小。如果应用以上方法,此题最坏情况应为:O(N*W*c[i])。

我们需要使用二进制,任何一个数都可以由二的幂表示。

比如Ci = 14,我们可以把它化成如下4个物品:

重量是Wi,体积是Vi

重量是2 * Wi , 体积是2 * Vi

重量是4 * Wi , 体积是4 * Vi

重量是7 * Wi , 体积是7 * Vi

我们用这4个物品代替原来的14个物品。时间复杂变为O(W*sigma(logC[i]))。

int dp[50005];
int v
,w
,c
;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++)
scanf("%d%d%d",&v[i],&w[i],&c[i]);
for(int i = 1; i <= n; i++)
{
for(int k = 1; k <= c[i]; k*=2)
{
for(int j = m; j >= v[i]*k; j--)
dp[j] = max(dp[j],dp[j-v[i]*k]+w[i]*k);
c[i] -= k;
}
int k = c[i];
for(int j = m; j >= v[i]*k; j--)
dp[j] = max(dp[j],dp[j-v[i]*k]+w[i]*k);
}
printf("%d\n",dp[m]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: